我过去常常为 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
};
}
}
}
}
数据库
最佳答案
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/