gpt4 book ai didi

entity-framework - 使用 Entity Framework 和 where 查询而不创建大量查询(避免 N+1)

转载 作者:行者123 更新时间:2023-12-04 07:21:12 24 4
gpt4 key购买 nike

我一直在使用一种设计模式,在使用 Entity Framework Profiler 之后,它看起来可能非常愚蠢。

我已经扩展了我的实体类以具有属性,这些属性是与该实体关联的集合的过滤 View 。像这样:

public IEnumerable<Member> ActiveMembers
{
get
{
return Members.Where(t => t.LeftDate == null);
}
}

因为我主要对还没有离开俱乐部的成员(member)感兴趣,所以这个属性非常有用而且似乎很有意义。

但是,通过运行 EF Profiler,我现在知道这通常会导致 N+1 问题。如果我遍历成员并且还想显示他们的地址,那么每个地址请求都会导致额外的数据库查询。

我从这个知道question I asked我可以将我的属性(property)修改为:

return Members.CreateSourceQuery().Include("Address")
.Where(t => t.LeftClubDate == null);

在这种情况下,这会消除 N+1 问题,但我并不总是想要地址信息,我可能想要跟随 Member 的另一个导航属性。

理想情况下,我希望能够保持过滤属性(如 ActiveMembers)的灵 active ,并能够在事后决定在查询中包含哪些属性。像这样:

var membersToDisplay = ActiveMembers.Include("Address").ToList();

这可能吗,还是我需要重新思考我的过滤属性想法?

最佳答案

不,不可能在 IEnumerable 上调用 IncludeIncludeObjectQuery/DbQuery 的特性。可以在 IQueryable 上调用 Include(使用 EFv4.1 或自定义扩展),但它仍然在内部将传递的查询转换为 ObjectQueryDbQuery 并在无法完成转换时抛出异常。您必须重新设计您的应用程序。

I don't always want the address information and I might want to follow another navigation property from Member.

您必须根据当前需求填充数据,否则将面临 N+1 问题。例如,您可以使用单独的 linq 查询:

var clubId = ActiveClub.Id;
var members = (from member in context.Members.Include("Address")
where member.LeftDate == null and member.ClubId == clubId
select member).ToList();

关于entity-framework - 使用 Entity Framework 和 where 查询而不创建大量查询(避免 N+1),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6001896/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com