2013-03-12 1 views
7

System.Linq.Expressions.Expression 클래스를 사용하여 SQL "WHERE"절을 동적으로 작성합니다. 간단한 절 (예 :LINQ 쿼리 용 식 트리가있는 IQueryable.Any 빌드

var equalTarget = Expression.Constant(phaseCode, typeof(int?)); 
var phaseEquals = Expression.Equal(Expression.PropertyOrField(projParam, "PhaseCode"), equalTarget); 

그러나, 지금은 프로젝트가 특정 그룹에 할당 된 경우 것입니다 레코드를 반환하는 식을 구축하기 위해 노력하고있어 "PhaseCode = X"절을 추가하기 위해, 나는 다음을 수행합니다. 프로젝트와 그룹은 다 - 대 - 다 관계가 있습니다. 다음과 같이 식 트리없이, 내가 할 것 :

db.Projects.Where(p => .... && p.GroupsAssigned.Any(g => g.ID == groupId)) 

그러나, 나는 식 클래스와 그것을 표현하는 방법을 찾을 수없는 것. 내가 알아낼 수없는 두 가지 사실이 있습니다

  • 방법 x.Any을 수행하는 방법에 테이블
  • 사이의 관계()

어떤 도움을 크게 감사를 통과하기는.

답변

10

Enumerable.Any 또는 Queryable.Any과 같은 확장 메서드를 호출하는 것은 WHERE 절에 대해 만든 시퀀스 및 람다 식의 정적 메서드 호출 일뿐입니다. 이 당신을 통해이 작업을 수행 할 수없는 것을 이상하게 보이지만

static Expression BuildAny<TSource>(Expression<Func<TSource, bool>> predicate) 
{ 
    var overload = typeof(Queryable).GetMethods("Any") 
           .Single(mi => mi.GetParameters().Count() == 2); 
    var call = Expression.Call(
     overload, 
     Expression.PropertyOrField(projParam, "GroupsAssigned"), 
     predicate); 

    return call; 
} 

: Queryable.Any<T>를 들어,이 방법으로이 문제를 롤업해야합니다

// for Enumerable.Any<T>(IEnumerable<T>,Predicate<T>) 
var overload = typeof(Enumerable).GetMethods("Any") 
           .Single(mi => mi.GetParameters().Count() == 2); 
var call = Expression.Call(
    overload, 
    Expression.PropertyOrField(projParam, "GroupsAssigned"), 
    anyLambda);  

:이 작업을 수행 할 Expression.Call을 사용할 수 있습니다 정상적인 쿼리.

+0

해결책 주셔서 감사합니다. Expression.Call()은 내가 필요한 것입니다. 귀하의 질문에 대답하기 위해,이 경우에는 정상적인 쿼리를 수행 할 수 없습니다. 왜냐하면 컴파일 타임에 WHERE 문에서 얼마나 많은 AND 부분을 가질 지 모르기 때문입니다. 그것은 모두 사용자가 검색 양식에서 선택한 항목에 따라 다릅니다. 표현식 트리를 구성하는 것이 유일한 유효한 솔루션 인 것 같습니다. –

+0

고마워, 내가 실수로 전화 했어. 'typeof (Queryable) .GetMethods ("Any"). (mi => mi.GetParameters(). Count() == 2); : typeof (열거 가능) .GetMethods ("Any"). (mi => mi.GetParameters(). Count() == 2); –