如何在运行时动态组合一组 LINQ 查询?

How can I dynamically combine a set of LINQ queries at runtime?

编辑:试图让我的问题更清楚一点。

我正在尝试构建一个 LINQ 表达式,它是几个 LINQ 语句的交集。现在,我可以手动将两个语句交叉在一起,并且得到了想要的结果。

        var results = 
                context.UserBooleanAttributes.Where(x => x.UserAttributeID == 1 && x.Value).Select(a => a.User)
            .Intersect(
                context.UserBooleanAttributes.Where(y => y.UserAttributeID == 2 && y.Value).Select(b => b.User)
            );

         Assert.Equal(100,results.Count());

我的目标是动态构建它,例如使用 for 循环。因为我使用的是 LINQ,所以我想推迟执行,直到我实际调用某些强制执行的 results

看来您只需要 User:

的列表
var list = new List<User>();

然后你可以添加每组结果,当你得到它们时:

list.AddRange(someUsers);

如果 User 是一个 class,您可以对其执行 Intersect,并且您只需要不同的值(您的代码中似乎就是这种情况),请考虑这样做一口气,最后调用 Distinct():

var attrIDs = Enumerable.Range(1, xTimes);

list.AddRange(context.UserBooleanAttributes
                     .Where(x => attrIDs.Contains(x.UserAttributeID) && x.Value)
                     .Select(a => a.User)
                     .Distinct());

这里有几个问题。首先是我需要一种方法来声明我的匿名变量以在循环外使用。我通过使用 IQueryable allBooleansTrue 来做到这一点。我给它分配了一个非空值,让 Resharper 停止烦扰我。第二个问题是我 运行 进入了著名的 closures issue。我使用 int copy = i

解决了这个问题
        IQueryable<User> allBooleansTrue = new List<User>().AsQueryable();
        for (int i = 1; i <= numBools; i++)
        {
            int copy = i; //workaround to prevent closures using reference
            var q = context.UserBooleanAttributes.Where(y => y.UserAttributeID == copy && y.Value)
                .Select(a => a.User);
            if (i == 1)
                allBooleansTrue = q;
            else
                allBooleansTrue = allBooleansTrue.Intersect(q);

第一次迭代用 LINQ 语句替换了我的外部变量 (allBooleansTrue) 的内容。其他迭代执行交集。这里有点 hacky,但这似乎有效(到目前为止)。我想我应该使用表达式树,但那是另一天的事了。

抱歉,我为原来的 post 稍微更改了我的代码,但我实在是太累了,从我的测试 class.

中复制了这个

您的代码可以重构,以获取多个用户列表:

IEnumerable<IEnumerable<User>> GetListOfListsOfUsers(int xTimes)
{
    for (int i = 1; i <= xTimes; i++)
    {
        var someUsers = context.UserBooleanAttributes
                               .Where(x => x.UserAttributeID == i && x.Value == true)
                               .Select(a => a.User);
        yield return someUsers;
    }
}

var listOfListsOfUsers = GetListOfListsOfUsers(xTimes);

问题现在变成了intersection of multiple lists:

var intersection = listOfListsOfUsers.Aggregate((previousList, nextList) => previousList.Intersect(nextList));