Я хочу объединить некоторые выражения Linq, поэтому я помогу из нижеприведенных статей:
http://www.c-sharpcorner.com/uploadfile/04fe4a/predicate-combinators-in-linq/ и http://thanhhh.blogspot.com/2011/10/linq-to-entities-predicatebuilder-and.html
и у меня есть общий список:
List<long> lstPA = new List<long>() { 2, 3 }; // the numbers can be added or removed
если я использую под кодом для комбинирования выражения linq, я получаю правильные результаты (записи) из db (я использую Entity Framework 4.0):
var exp1 = Predicate.FalseExpression<posts>();
exp1 = exp1.Or(x => x.post_author == 2);
exp1 = exp1.Or(x => x.post_author == 3);
но когда я совмещаю выражение linq в цикле foreach Как это:
var exp1 = Predicate.FalseExpression<posts>();
foreach (long id in lstPA)
{
exp1 = exp1.Or(x => x.post_author == id);
}
Я не могу получить правильный результат (записи) из db.
что такое различие между двумя блоками кода и как решить эту проблему (я должен использовать цикл foreach)?
Я считаю, что ваша проблема связана с закрытием. Идентификатор переменной присваивается выражению и он обновляется до нового значения каждый раз, когда вы выполняете цикл. Чтобы использовать его, вы хотите создать индивидуальную переменную с областью.
var exp1 = Predicate.FalseExpression<posts>();
foreach (long i in lstPA)
{
long id = i;
exp1 = exp1.Or(x => x.post_author == id);
}
Однако в этом случае вы можете просто использовать предложение contains.
expr1 = x => lstPA.Contains(x.post_author);
Похож на экземпляр проблемы закрытия foreach. Вы передаете два раза один и тот же идентификатор в базу данных. Примените исправление, описанное в связанном вопросе: Скопируйте id
в переменную внутри цикла.
это кажется мне проблемой с замыканиями и циклами. Id ссылается на переменную цикла и будет продолжать делать это, что означает, что она изменяется и читает что-то вроде
exp1 = exp1.Or(x => x.post_author == 3);
exp1 = exp1.Or(x => x.post_author == 3);
когда разворачивается. Чтобы исправить это, вы можете попробовать:
var exp1 = Predicate.FalseExpression<posts>();
foreach (long id in lstPA)
{
long tempID = id;
exp1 = exp1.Or(x => x.post_author == tempID);
}
это гарантирует, что временная переменная, которая была создана в цикле и никогда не изменена после этого, будет использоваться вместо переменной цикла, которая мутируется во время ее курса.