EF6(非EF Core)使用导航属性替代LINQ Join实现多表关联查询
第一步:修正实体类映射配置
你之前配置报错的核心原因是没有明确指定外键关联规则,EF按照默认映射规则匹配字段才会出现关联错字段的问题。首先删掉Customer类里不属于表字段的ShipToCustomerID,再给导航属性加上正确的配置注解即可:
Orders实体类
[Table("Orders")] public partial class Orders { [Key] [StringLength(17)] public string OrderID { get; set; } // 关联Customer主键的外键字段 public int ShipToCustomerID { get; set; } // 明确标注该导航属性的外键是ShipToCustomerID [ForeignKey(nameof(ShipToCustomerID))] public Customer Customer { get; set; } }
Customer实体类
如果是一对一关系(一个客户对应一个订单),写法如下:
[Table("Customer")] public partial class Customer { [Key] // 明确标注主键 public int CustomerID { get; set; } public string AccountNumber { get; set; } // 明确标注该导航属性对应Orders实体里的Customer属性 [InverseProperty(nameof(Orders.Customer))] public Orders Order { get; set; } }
如果实际业务是一对多关系(一个客户对应多个订单),把导航属性改成集合类型即可:
// 加virtual可支持懒加载,不需要可以去掉 public virtual ICollection<Orders> Orders { get; set; }
可选:用Fluent API配置(不想给实体加注解的场景)
如果不想在实体类上加特性,也可以在DbContext的OnModelCreating方法里全局配置关系:
protected override void OnModelCreating(DbModelBuilder modelBuilder) { // 配置关联规则:Orders依赖Customer,外键是ShipToCustomerID modelBuilder.Entity<Orders>() .HasRequired(o => o.Customer) // 若订单可无对应客户则改成HasOptional .WithMany(c => c.Orders) // 若为一对一则改成.WithRequired(c=>c.Order) .HasForeignKey(o => o.ShipToCustomerID); }
第二步:用导航属性实现查询
配置完成后,原来的Join查询可以简化为如下写法,输出结果和之前完全一致:
using (var context = new OrderDetailsGeneral1()) { var orders = context.Orders .Include(o => o.Customer) // 不需要懒加载的话可以加Include即时加载关联数据 .Where(o => o.OrderID == "7150615") .Select(o => new { OrderID = o.OrderID, CustomerID = o.Customer.AccountNumber }) .ToList(); return Json(orders); }
内容的提问来源于stack exchange,提问作者SUIIIII
相关产品推荐
相关产品推荐

