c# - 如何避免 EF 生成的查询中的 N+1

标签 c# entity-framework entity-framework-5

我过去常常为 POCO 中的多对多关系或关系 ID 生成所有帮助程序表,如 UsergroupUsers,但现在我希望 EF 来处理它们。现在我认为这毕竟不是一个好主意。

问题

当我尝试获取特定用户的所有 UsergroupDynamicField 时,它会为每个用户所在的用户组生成 N+1 查询。

Here我通过简单地说明 Usergroups 将是 IQUeriable 而不是 IEnumerable 来解决这个问题。现在我不能那样做,因为 EF 不会映射它,它必须是 ICollection

代码

public class User
{
    ...
    public virtual ICollection<Usergroup> Usergroups { get; set; }
    public IEnumerable<UserField> Fields
    {
        get
        {
            var fields = this.Usergroups.SelectMany(x => x.UsergroupDynamicFields); // N + 1 for every Usergroup

            foreach (var field in fields)
            {
                yield return new UserField
                {
                    Name = field.Name
                };
            }
        }
    }
}

数据库

DB DB2

最佳答案

Here I overcommed this problem by simply stating that Usergroups will be IQUeriable instead of IEnumerable. Now I cannot do that because EF won't map it, it has to be ICollection.

但是最终实现 ICollection 的类是 EntityCollection<T> .这个集合有一个 CreateSourceQuery() function你可以使用:

var usergroupsQuery = ((EntityCollection<UserGroup>)this.Usergroups).CreateSourceQuery();
var fields = usergroupsQuery.SelectMany(x => x.UsergroupDynamicFields);

更新:正如评论中指出的那样,ICollection<T>将仅使用 EntityCollection<T> 实现当可以并启用更改跟踪时(非密封类和所有相关属性 virtual )。您可以通过其他方式创建查询:

var usergroupsQuery = db.Entry(this).Collection(u => u.Usergroups).Query();
var fields = usergroupsQuery.SelectMany(x => x.UsergroupDynamicFields);

请注意,这需要您有权访问 db不知何故。

关于c# - 如何避免 EF 生成的查询中的 N+1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17858004/

相关文章:

c# - Entity Framework 4.0,添加不包含主键的SQL Server View

c# - AddOrUpdate 未按预期工作并产生重复项

c# - 更有效地实现大量事件

c# - 所有 WPF 控件属性都是依赖属性。对或错?

entity-framework - 在 Entity Framework 中使用 lambda 语法进行多个左连接

.net - 使用复合键在模型中创建关系会引发 "Property is part of key and can' t be modded”异常

c# - 未被发现的 POCO 类要求

c# - 如何在 VS 2010 中为 XAML 设计器初始化类?

c# - Google Datastore 身份验证问题 - C#

asp.net - 如何为 Entity Framework DBContext 显式指定连接字符串