所以我最近在Entity Framework 6中做了很多编程,而且我对于预先加载的某些行为感到非常恼火。
拿这个:
IEnumerable<Customer>
我知道我实际上可以在EF中启用延迟加载,但这是我想避免做的事情,因为它只会将其变成选择N + 1问题。
我不喜欢的是,两个查询实际上都返回了不同类型的数据,即使它们的签名本质上是public class CustomerRepo {
IEnumerable<T> GetCertainCustomers<T>(...);
IEnumerable<T> DifferentCustomerQuery<T>(...);
IEnumerable<T> YetAnotherQuery<T>(...);
}
public class Customer {...}
public class CustomerWithOrders : Customer { public IEnumerable<Order> Orders { get; set;} }
public class CustomerWithPaymentMethods : Customer { public IEnumerable<Order> Orders { get; set;} }
如果我要在EF上编写我自己的存储库,我&# 39; d喜欢做这样的事情:
#!/usr/bin/env awk
BEGIN { state = 0; }
/<Person>/ { if (state == 0) { print "#Person"; state = 1 } else { state = 0; print } next }
/<Address>/ { if (state == 1) { print "#Addr"; state = 2 } else { state = 0; print } next }
/<\/Address>/ { if (state == 2) { print "#CloseAddr"; state = 3 } else { state = 0; print } next }
/^\s*$/ { if (state == 3) { print "#Blank"; state = 3 } else { state = 0; print } next }
/<\/Person>/ { if (state == 3 || state == 4) { print "#ClosePerson"; state = 0 } else { state = 0; print } next }
{ print } # Default action
如上所述实际上可以正常工作,在给定类型参数T的情况下,存储库会执行正确的预先加载量。
我的问题是如果你有超过2-3种不同的渴望加载选项,那么类型的数量会爆炸,更不用说当你想要加载多个关系时会发生什么!< /强>
仅供参考,以上所有代码仅供参考,但并非真实。
答案 0 :(得分:0)
如果您特别关注空引用异常 ,则默认情况下您只需将Orders
设为空集合。
例如:
public class Customer
{
public virtual List<Order> Orders { get; set; }
public Customer()
{
Orders = new List<Order>();
}
}
加载没有.Include(c => c.Order)
的客户意味着该集合将为空但 null 。这意味着你的例子:
customers.SelectMany(c => c.Orders).DoSomething(...);
customersWithOrders.SelectMany(c => c.Orders).DoSomething(...);
两者都有效(第一个只是什么都不做,因为集合是空的)。
在任何情况下, 应该在适当的时候进行空检查。如果您的方法要求客户订购,应检查。定义一个仅仅描述对象中哪些信息为空或哪些不是null的类是一个坏主意。