的WebAPI
让我们有一个人类与许多一对多关系,如汽车,宠物,儿童......
和 PersonRepository 我必须包含所有关系及其关系,或者只是禁用延迟加载
public Person getPerson()
{
...
using (db = new DbContext())
{
// var person = linq-query
// return person;
}
...
}
所以在我的控制器中我有满载关系及其关系的人。
如果存在具有许多嵌套关系的对象数组,则效率低且内存要求高。
我如何在存储库之外延迟加载属性或者这个问题的一般解决方案是什么?
答案 0 :(得分:1)
我如何在存储库之外延迟加载属性或者这个问题的一般解决方案是什么?
如果您想知道在上下文中禁用延迟加载后如何加载导航属性,那么您有以下解决方案:
渴望加载,使用包含DbSet的方法,如下所示:
db.Persons.Include(p => p.Cars).Include(p => p.Pets).Include(p => p.Children).Where(p => p.Id == personId);
明确加载,在您的条目中使用更改跟踪器和Load
方法,如下所示:db.entry(person).Collection(p => p.Cars).Load();
我在EF和Repository Pattern中看到的解决方案是使用集合lambda表达式作为方法的参数,如下所示:
public Person GetPerson(params Expression<Func<Person, object>>[] includes)
{
using (var db = new DbContext())
{
IQueryable<Person> query = db.Posts;
Array.ForEach(includes, expression => query = query.Include(expression));
return query.FirstOrDefault();
}
}
您可以这样使用它:GetPerson(p => P.Cars, p => p.Pets, p => p.Children)
使用此解决方案,您只需将它们指定为方法的参数,即可加载所需的导航属性。
答案 1 :(得分:0)
答案 2 :(得分:0)
据我所知,没有单一的通用解决方案。
所以你可以尝试这些案例:
不要关闭只读DbContext
(只是不要忘记禁用跟踪)。在某些情况下,例如Web请求,您可以在请求开始时创建DbContext
,并将其置于最后。
忘记记忆要求。如果您计划从SQL读取2Mb数据,那么您的设计有问题。 5Kb,30Kb不是大数据。
考虑缓存。让所需的数据始终可用。
重构您的接口以仅加载必要的数据。 F.E.附加方法LoadPersonsWithAddresses
,LoadPersonsWithFamily
等。
答案 3 :(得分:0)
在您的集合上显式调用load方法。这会导致延迟负载。