我在加载Entity Framework集合属性时遇到问题。
当我尝试通过父对象急切加载集合时,collection属性保持为null。但是,在查询中直接选择子集合属性时,将返回正确的子对象。
这是我的代码:
var odr = Db.Orders
.Include(o => o.Items)
.Where(x => x.ID == orderID)
.FirstOrDefault();
var manualItems = Db.Orders
.Where(x => x.ID == orderID)
.Select(x => x.Items)
.ToList();
执行此操作时,odr.Items
为空,但manualItems
具有正确的值!
更奇怪的是:我在OrderItem
类(odr.Items
和manualItems
的类型)的某些属性设置器上设置了断点,并发现实体框架 正确检索,创建和填充子OrderItem
个对象。它只是没有设置odr.Items
属性。
这里是类和映射,供参考:
顺序
public class Order
{
public string ID { get; set; }
<snip>
public virtual ICollection<OrderItem> Items { get; set; }
}
订购商品
public class OrderItem : IOrderItem
{
public int ID { get; set; }
public string OrderID { get; set; } //I set a breakpoint on the setter here, it was called each time
public string ProductSku { get; set; }
public string ProductName { get; set; }
}
订单映射
public class OrderMap : EntityTypeConfiguration<Order>
{
public OrderMap() : base()
{
HasKey(m => m.ID);
Property(m => m.ID).HasColumnName("id").HasMaxLength(50);
<snip>
HasMany(m => m.Items).WithOptional().HasForeignKey(x => x.OrderID);
ToTable("order_details");
}
}
订单商品映射
public class OrderItemMap : EntityTypeConfiguration<OrderItem>
{
public OrderItemMap() : base()
{
HasKey(m => m.ID);
Property(m => m.ID).HasColumnName("id");
Property(m => m.OrderID).HasColumnName("order_id");
Property(m => m.ProductSku).HasColumnName("product_sku");
Property(m => m.ProductName).HasColumnName("product_name");
ToTable("order_items");
}
}
我正在使用.NET 4.6和Entity Framework 6.1.3
答案 0 :(得分:0)
事实证明,问题的核心在于Order
上的ID字段是一个字符串。
创建订单后,ID在代码中的某处更改为全部小写。因此,OrderItem.OrderID
匹配Order.ID
- 套管不同。
至于为什么
var odr = Db.Orders
.Include(o => o.Items)
.Where(x => x.ID == orderID)
.FirstOrDefault();
工作,但
var manualItems = Db.Orders
.Where(x => x.ID == orderID)
.Select(x => x.Items)
.ToList();
没有 - 在生成的SQL查询中可能会有轻微差异导致SQL服务器在后一种情况下忽略套管而不是前者。它也可能是Entity Framework本身对两个ID字段进行查询后验证。