2010-05-20 2 views
2

SubSonic 3.04의 SimpleRepository에서 람다 식 내에서 Contains 연산을 수행 할 수 없습니다. 나는 오류 메시지가람다에 SimpleRepository.Find가 포함되어 있습니다.

SimpleRepository repo = new SimpleRepository("ConnectionString"); 

List<int> userIds = new List<int>(); 
userIds.Add(1); 
userIds.Add(3); 

List<User> users = repo.Find<User>(x => userIds.Contains(x.Id)).ToList(); 

: 여기에 사소한 예입니다

변수 'X'가 정의되어 있지 않고 유형 '사용자' ''범위에서 참조의

여기에 뭔가가 빠져 있거나 SubSonic이 람다 식에서 Contains을 지원하지 않습니까? 그렇지 않다면 어떻게 될까요?

+0

부끄러운는 롭 을 모르는 http://blog.wekeroad.com/blog/creating-in-queries-with-linq-to을 싫어하는 것 : 그래서 다음과 같은 작업을해야합니다 -sql/ – jvenema

답변

4

: 당신은 아마 explictely은 OR 조건을 정의에 의존해야 :

x => x.Id == {id1} OR x.Id == {id2} OR x.Id == {id3} 

이 사소한 시나리오이지만, GetContainsId<User>(ids, repo) 제공된 목록에서 뭔가를 일치 ID로 모든 사용자를 찾을 방법을 보여줍니다.

public List<T> GetContainsId<T>(List<int> ids, SimpleRepository repo) 
    where T : Record, new() // `Record` is a base class with property Id 
{ 
    ParameterExpression x = Expression.Parameter(typeof(T), "x"); 
    LambdaExpression expr; 
    if (ids.Count == 0) 
    { 
     expr = Expression.Lambda(LambdaExpression.Constant(false), x); 
    } 
    else 
    { 
     expr = Expression.Lambda(BuildEqual(x, ids.ToArray()), x); 
    } 

    return repo.Find<T>((Expression<Func<T,bool>>)expr).ToList(); 
} 

private BinaryExpression BuildEqual(ParameterExpression x, int id) 
{ 
    MemberExpression left = Expression.Property(x, "Id"); 
    ConstantExpression right = Expression.Constant(id); 
    return Expression.Equal(left, right); 
} 

private BinaryExpression BuildEqual(ParameterExpression x, int[] ids, int pos = 0) 
{ 
    int id = ids[pos]; 
    pos++; 

    if (pos == ids.Length) 
    { 
     return BuildEqual(x, id); 
    } 

    return Expression.OrElse(BuildEqual(x, ids, pos), BuildEqual(x, id)); 
} 
+0

Or 식을 작성하기위한 작업 순서에 작은 버그가 있음을 알았습니다. 예제에서 수정되었습니다. – Anton

0

아마도 Subsonic은 해당 목록을 SQL 데이터베이스에서 실행할 수있는 것으로 변환 할 수 없으므로 userIds.Contains을 변환 할 수 없습니다.

x => guids.Contains(x.Guid) 
x => guids.Any(y => y == x.Guid) 

은 ... 우리가 생성하는 사용자 정의 람다 식 작성기를 쓰기 ... 이들 중 어느 것도 제대로 작동하기 때문에

repo.Find<User>(x => x.Id == 1 || x.Id == 3).ToList(); 
0

목록 대신 IEnumerable을 사용하면이 방법이 유용 할 것입니다. ... 그들에

SimpleRepository repo = new SimpleRepository("ConnectionString"); 

IEnumerable<int> userIds = new List<int>(); 
userIds.Add(1); 
userIds.Add(3); 

List<User> users = repo.Find<User>(x => userIds.Contains(x.Id)).ToList(); 
+0

내 코드에 다른 문제가없는 한 저에게 도움이되지 않습니다. 확실합니까? (또한, Subsonic 3.1은 어떻게 진행되고 있습니까?) – Anton

+0

hmmm, userIds.Contains (x.Id.ToString())을 해보십시오.) - 이번 주말에 메일 링리스트에 업데이트를 게시 할 시점에 3.1이 보류 중입니다. . –