将数据库架构转换为与 Entity Framework Code First 开发相关的模型






2.43/5 (4投票s)
如何从一组数据库表创建一组数据模型。
引言
在本文中,我将从一个表图开始,并展示如何从中创建必要的数据模型,用于实体框架代码优先开发。
考虑以下表图
上面的图表显示了一个包含五个表的数据库模式。在接下来的讨论中,我们将看到如何创建必要的数据模型来设置与这些表的映射。
员工表的数据模型类
[Table("Employees")]
public class Employee
{
[Key]
public int EmployeeID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string Title { get; set; }
public string TitleOfCourtesy { get; set; }
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime BirthDate { get; set; }
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime HireDate { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string Region { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public string HomePhone { get; set; }
public string Extension { get; set; }
public byte[] Photo { get; set; }
public string Notes { get; set; }
public int? ReportsTo { get; set; }
public string PhotoPath { get; set; }
[ForeignKey("ReportsTo")]
public virtual Employee ReportsEmployees { get; set; }
public virtual ICollection<Orders> Orders { get; set; }
}
这里 [Key]
属性设置主键。
以下两行用于设置递归关系,这意味着引用自身。外键列名为 ReportsTo
。
[ForeignKey("ReportsTo")]
public virtual Employee ReportsEmployees { get; set; }
[Table("Employees")]
属性用于重命名数据库表。
以下行显示员工表与订单表之间存在一对多关系。
public virtual ICollection<Orders> Orders { get; set; }
承运商表的数据模型类
public class Shippers
{
[Key]
public int ShipperID { get; set; }
public string CompanyName { get; set; }
public string Phone { get; set; }
public virtual ICollection<Orders> Orders { get; set; }
}
这里 [Key]
用于主键设置,并且承运商表与订单表之间存在一对多关系。
订单表的数据模型类
public class Orders
{
[Key]
public int OrderID { get; set; }
public int? CustomerID { get; set; }
public int? EmployeeID { get; set; }
public DateTime OrderDate { get; set; }
public DateTime RequiredDate { get; set; }
public DateTime ShippedDate { get; set; }
public int? ShipVia { get; set; }
public Decimal Freight { get; set; }
public string ShipName { get; set; }
public string ShipAddress { get; set; }
public string ShipCity { get; set; }
public string ShipRegion { get; set; }
public string ShipPostalCode { get; set; }
public string ShipCountry { get; set; }
public virtual Employee Employee { get; set; }
[ForeignKey("ShipVia")]
public virtual Shippers Shipper { get; set; }
public virtual ICollection<OrderDetails> OrderDetails { get; set; }
}
订单表与员工表和承运商表之间存在多对一关系,并且与订单详情表之间存在一对多关系。
[ForeignKey("ShipVia")]
显示外键。
产品表的数据模型类
public class Products
{
[Key]
public int ProductID { get; set; }
public string ProductName { get; set; }
public int? SupplierID { get; set; }
public int? CategoryID { get; set; }
public string QuantityPerUnit { get; set; }
public decimal UnitPrice { get; set; }
public Int16 UnitsInStock { get; set; }
public Int16 UnitsOnOrder { get; set; }
public Int16 ReorderLevel { get; set; }
public bool Discontinued { get; set; }
public virtual ICollection<OrderDetails> OrderDetails { get; set; }
}
产品表与订单详情表之间存在一对多关系。
订单详情表的数据模型类
[Table("Order Details")]
public class OrderDetails
{
public int OrderID { get; set; }
public int ProductID { get; set; }
public decimal UnitPrice { get; set; }
public Int16 Quantity { get; set; }
public Single Discount { get; set; }
public virtual Orders Order { get; set; }
public virtual Products Product { get; set; }
}
订单详情表与订单表和产品表之间都存在多对一关系。这意味着订单表和产品表之间存在多对多关系。
为了设置订单详情表中的复合主键,我编写了以下 Fluent API
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<OrderDetails>()
.HasKey(e => new { e.OrderID, e.ProductID });
}
结论
Fluent API 也可以用于设置与表的映射。我使用数据标注设置了大部分映射,并在这里使用 Fluent API 进行单次设置。