Linq多个查询位置

kh2*_*h25 10 .net c# linq entity-framework-4

我有一个问题,建立一个相当沉重的linq查询.基本上我有一种情况,我需要在循环中执行子查询以过滤从数据库返回的匹配数.示例代码在以下循环中:

        foreach (Guid parent in parentAttributes)
        {
            var subQuery = from sc in db.tSearchIndexes
                           join a in db.tAttributes on sc.AttributeGUID equals a.GUID
                           join pc in db.tPeopleIndexes on a.GUID equals pc.AttributeGUID
                           where a.RelatedGUID == parent && userId == pc.CPSGUID                             
                           select sc.CPSGUID;

            query = query.Where(x => subQuery.Contains(x.Id));
         }
Run Code Online (Sandbox Code Playgroud)

当我随后在查询变量上调用ToList()时,似乎只执行了一个子查询,并且我留下了一大堆我不需要的数据.但是这种方法有效:

       IList<Guid> temp = query.Select(x => x.Id).ToList();

        foreach (Guid parent in parentAttributes)
        {
            var subQuery = from sc in db.tSearchIndexes
                           join a in db.tAttributes on sc.AttributeGUID equals a.GUID
                           join pc in db.tPeopleIndexes on a.GUID equals pc.AttributeGUID
                           where a.RelatedGUID == parent && userId == pc.CPSGUID                             
                           select sc.CPSGUID;

            temp = temp.Intersect(subQuery).ToList();
        }

        query = query.Where(x => temp.Contains(x.Id));
Run Code Online (Sandbox Code Playgroud)

不幸的是,这种方法很糟糕,因为它导致对远程数据库的多个查询,如果我能使它工作的初始方法只会导致单次命中.有任何想法吗?

dri*_*iis 8

我认为你正在尝试捕获用于过滤的lambda表达式中的循环变量.也称为访问修改后的闭包错误.

试试这个:

   foreach (Guid parentLoop in parentAttributes)
    {
        var parent = parentLoop;
        var subQuery = from sc in db.tSearchIndexes
                       join a in db.tAttributes on sc.AttributeGUID equals a.GUID
                       join pc in db.tPeopleIndexes on a.GUID equals pc.AttributeGUID
                       where a.RelatedGUID == parent && userId == pc.CPSGUID                             
                       select sc.CPSGUID;

        query = query.Where(x => subQuery.Contains(x.Id));
     }
Run Code Online (Sandbox Code Playgroud)

问题是捕获parent闭包中的变量(将LINQ语法转换为),这会导致所有subQueryes以相同的父ID运行.

发生的事情是编译器生成一个类来保存委托和委托访问的局部变量.编译器为每个循环重用该类的相同实例; 因此,一旦查询执行,所有的Wheres都使用相同的parentGuid 执行,即最后执行.

声明parent循环范围内部会导致编译器基本上复制具有正确值的变量.

起初这可能有点难以掌握,所以如果这是第一次击中你; 我推荐这两篇文章作为背景和详尽的解释: