
我不太习惯通过CodeFirst去维护数据库(尽管这是未来实现自动编程的必经之路),还是喜欢通过数据库设计工具如PowerDesigner去建表。如果不想对EF的实体和数据表做什么映射的话,就要注意默认映射规则。以订单表(Order)和订单明细表(OrdersDetails)这类一对多的关系表为例。
数据库建表脚本:
create table Orders ( id ,), OrderNo nvarchar(), TotalAmount ,), OrderTime datetime default getdate() ) create table OrdersDetails ( id ,), Orders_Id int, Product_Id int, ProductName nvarchar(), AddTime datetime default getdate() ) create table Product ( id ,), name nvarchar(), ) insert into Orders(OrderNo,TotalAmount) values(); insert into Orders(OrderNo,TotalAmount) values(); insert into Orders(OrderNo,TotalAmount) values(); insert into Orders(OrderNo,TotalAmount) values(); insert into Orders(OrderNo,TotalAmount) values(); insert into OrdersDetails(Orders_Id,Product_Id,ProductName) values(,,'Iphone8'); insert into OrdersDetails(Orders_Id,Product_Id,ProductName) values(,,'MI6'); insert into OrdersDetails(Orders_Id,Product_Id,ProductName) values(,,'HW7'); insert into OrdersDetails(Orders_Id,Product_Id,ProductName) values(,,'MZ'); insert into Product(Name) values('Iphone8'); insert into Product(Name) values('MI6'); insert into Product(Name) values('HW7'); insert into Product(Name) values('MZ');
总结的几个规则:
1.明细表的表明要用复数形式即 OrdersDetails
2.外键关系要 关联表名称_Id:Orders_Id,即使实体类是OrdersId也是去查找Orders_Id列
3.除了关联外键外其他字段最好用驼峰式命名,不要包含_或-
实体类和DbContext如下:
public class OrderManamgerDBContext : DbContext { public DbSet<Orders> Orders { get; set; } public DbSet<OrdersDetails> OrdersDetails { get; set; } public OrderManamgerDBContext() { } public OrderManamgerDBContext(string connectionString) : base(connectionString) { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new OrdersDetailsConfiguration()); base.OnModelCreating(modelBuilder); } } public class OrdersDetailsConfiguration : EntityTypeConfiguration<OrdersDetails> { public OrdersDetailsConfiguration() { //不是按照EF默认规则命名的需要手动映射 //HasEntitySetName("OrdersDetails"); //Property(t => t.OrdersId).HasColumnName("Orders_Id"); //Property(t => t.ProductId).HasColumnName("Product_Id"); } } public class Orders { public int id { get; set; } public string OrderNo { get; set; } public decimal TotalAmount { get; set; } public DateTime OrderTime { get; set; } public List<OrdersDetails> OrdersDetail { get; set; } } public class OrdersDetails { public int id { get; set; } public int Orders_Id { get; set; } public int Product_Id { get; set; } public string ProductName { get; set; } public DateTime AddTime { get; set; } }
如果实体类和数据表字段命名方式不一样就需要手动映射:
public class OrdersDetail { public int id { get; set; } public int OrdersId { get; set; } public int ProductId { get; set; } public string ProductName { get; set; } public DateTime AddTime { get; set; } }
这个时候就要把DbContext中的注释放开
控制台程序,采用积极加载方式:
class EFTest { static OrderManamgerDBContext odmdb = new OrderManamgerDBContext("DbContext"); //static OrderManamgerDBContext odmdb = new OrderManamgerDBContext(ConfigurationManager.ConnectionStrings["DbContext"].ConnectionString); public static void Main(string[] args) { ); //var rlt = odmdb.Orders.Where(od => od.id == 1); foreach(var itm in rlt) { Console.WriteLine("单据编号 "+itm.OrderNo + "\r\n明细产品:"); foreach (var citm in itm.OrdersDetail) { Console.WriteLine(citm.ProductName); } } string sql = rlt.ToString(); Console.Read(); } }
建议能按照默认规则设计就按照默认规则设计,EF的一个初衷就是减少工作量