2014-07-25 4 views
1

루프에서 일부의 LINQ 표현을 결합, 그래서 난 기사를 아래에서 도움 방법 :C#을 내가 몇 가지의 LINQ 표현을 결합하려는

http://www.c-sharpcorner.com/uploadfile/04fe4a/predicate-combinators-in-linq/http://thanhhh.blogspot.com/2011/10/linq-to-entities-predicatebuilder-and.html

를 그리고 난 이런 일반적인 목록을 가지고 :

를 내 LINQ 식을 결합하기위한 내가 코드에서 사용하는 경우
List<long> lstPA = new List<long>() { 2, 3 }; // the numbers can be added or removed 

, 난 DB에서 올바른 결과 (레코드) 수 (내가 엔티티 프레임 워크 4.0 사용) :

012 3,516,
var exp1 = Predicate.FalseExpression<posts>();    
exp1 = exp1.Or(x => x.post_author == 2); 
exp1 = exp1.Or(x => x.post_author == 3); 

하지만 난 이런 foreach 루프에서 LINQ 식을 결합 할 때

var exp1 = Predicate.FalseExpression<posts>(); 
foreach (long id in lstPA) 
{ 
    exp1 = exp1.Or(x => x.post_author == id); 
} 

난 DB에서 올바른 결과 (기록)을 얻을 수 없습니다.

2 코드 블록 사이의 차이점은 무엇이며 어떻게이 문제를 해결할 수 있습니까 (foreach 루프를 사용해야합니까?)?

+0

당신은 훨씬 더 빠른 접근 방법 인 .Where (x => lstPA.Contains (x.post_author))로 뭔가를 할 수 있습니다. – slippyr4

+2

Google closure over 루프 변수입니다. –

답변

7

귀하의 문제는 폐쇄와 관련이 있다고 생각합니다. 변수 id는 표현식에 할당되고 반복 할 때마다 더 새로운 값으로 업데이트됩니다. 이를 사용하려면 개별적으로 범위가 지정된 변수를 만들고 싶습니다.

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); 
1

이것은 클로저 및 루프와 관련된 문제인 것처럼 보입니다. 이드 루프 변수를 참조하고 변경 의미와 전개 할 때

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); 
} 

.