【问题标题】:SelectMany makes too many queriesSelectMany 查询过多
【发布时间】:2013-07-17 21:45:27
【问题描述】:

我在用户组中有动态字段,我想根据用户组的用户来选择它们。

基本上我想模拟像.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?
    }
}

【问题讨论】:

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


    【解决方案1】:

    尝试将其转换为IQueryable&lt;T&gt; 而不是IEnumerable&lt;T&gt;:

    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 连接。

    【讨论】:

    • 该死!这很容易,我认为这会更难。谢谢:)
    • @Steve 很高兴为您提供帮助。通常,如果您将集合保留为 IQueryable&lt;T&gt;,则在其上执行的任何 Linq 方法都将在数据库上运行,而不是在本地运行的 IEnumerble&lt;T&gt;。但是,它们都利用了惰性执行,因此在您真正尝试获取结果之前它根本不会运行。
    • 是的,但DynamicFields 应该保留IEnumerable,因为它使用的是yield return,而我不能使用IQueriable。
    • 正确,yield return / yield break 仅在返回类型为 IEnumerable&lt;T&gt; 时有效,但是,是的,我想你明白了它的要点。编码愉快。
    • 嘿,但是如果我没有制作所有辅助表并让 EF 连接它们怎么办?我可以在这里选择:stackoverflow.com/questions/17858004/… 吗?
    猜你喜欢
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-30
    • 2016-05-30
    • 1970-01-01
    相关资源
    最近更新 更多