Ответ 1
Я думаю, что вы делаете особый случай захвата переменной цикла в выражении лямбда, используемом для фильтрации. Также известен как доступ к модифицированной ошибке закрытия.
Попробуйте следующее:
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));
}
Проблема заключается в захвате переменной parent
в замыкании (с которой преобразуется синтаксис LINQ), что приводит к запуску всех subQuery
es с одним и тем же родительским идентификатором.
Что происходит, так это компилятор, создающий класс для хранения делегата и локальных переменных, к которым обращается делегат. Компилятор повторно использует один и тот же экземпляр этого класса для каждого цикла; и поэтому, как только запрос выполняется, все Where
выполняются с тем же parent
Guid, а именно последним для выполнения.
Объявление parent
внутри области цикла приводит к тому, что компилятор должен сделать копию переменной с правильным значением.
Сначала это может быть сложно понять, поэтому, если это первый раз, когда он ударил вас; Я бы рекомендовал эти две статьи для фона и подробное объяснение:
- Eric Lippert: Закрытие по переменной цикла считается вредной и часть вторая.
- Джон Скит: Closures