SelectMany生成了过多的查询

3
我有一些用户组内的动态字段,我想根据用户所在的用户组选择它们。
基本上,我想模拟查询,例如.Where(x => x.UserGroupId == x || ...,否则需要大约20个查询才能获取动态字段。
也许我可以将整数数组作为UserGroupId传递,并使用||模拟查询。
这是我的示例,两个结果输出相同,唯一的区别是第一个需要向数据库发出20个查询,而第二个只需1个。
public IEnumerable<UserGroup> UserGroups
{
    get
    {
        var db = new MainDataContext();
        return db.UserGroupUsers.Where(x => x.UserId == this.Id).Select(x => x.UserGroup);
    }
}
public IEnumerable<UserDynamicField> DynamicFields
{
    get
    {
        var db = new MainDataContext();

        var fields = this.UserGroups.SelectMany(x => x.UserGroupDynamicFields); // 20+ queries

        var fields2 = db.UserGroupDynamicFields.Where(x =>
            x.UserGroupId == 1 ||
            x.UserGroupId == 2 ||
            x.UserGroupId == 3 ||
            x.UserGroupId == 4 ||
            x.UserGroupId == 5 ||
            x.UserGroupId == 6 ||
            x.UserGroupId == 7 ||
            x.UserGroupId == 8 ||
            x.UserGroupId == 9 ||
            x.UserGroupId == 10); // 1 query, maybe I can somehow pass array of Id's here?
    }
}
1个回答

2
尝试将其转换为 IQueryable<T> 而不是 IEnumerable<T>:
public IQueryable<UserGroup> UserGroups
{
    get
    {
        var db = new MainDataContext();
        return db.UserGroupUsers.Where(x => x.UserId == this.Id)
                                .Select(x => x.UserGroup);
    }
}
public IQueryable<UserDynamicField> DynamicFields
{
    get
    {
        // 1 query
        return this.UserGroups.SelectMany(x => x.UserGroupDynamicFields); 
    }
}

这将使Linq能够利用它不必在迭代之前将结果集拉入内存的优势,因此这将被翻译为传统的SQL连接。


该死!这很简单,我以为会更难。谢谢 :) - Stan
1
@Steve 很高兴能帮忙。一般来说,如果您将集合保留为 IQueryable<T>,则在其上执行的任何 Linq 方法都会在数据库上运行,而不是在本地运行的 IEnumerble<T>。但是,它们都利用了惰性执行,因此在您实际尝试获取结果之前,它根本不会运行。 - p.s.w.g
是的,但是DynamicFields应该保持为IEnumerable,因为它使用了yield return,而我不能在其上使用IQueryable - Stan
正确,yield return / yield break 只在返回类型为 IEnumerable<T> 时起作用,但是没错,我想你已经明白了。祝编程愉快。 - p.s.w.g
嘿,但是如果我没有创建所有的辅助表并让EF连接它们怎么办?我可以在这里有一个选项吗:https://dev59.com/l3TYa4cB1Zd3GeqPz-M_? - Stan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接