2012-11-05 2 views
3

저는 Entity Framework Linq 쿼리에 대한 비교 술어를 일반적으로 작성해야합니다. 리플렉션을 사용하고 있으며 아무런 문제없이 단일 레벨의 람다 식을 만들 수 있습니다. 그러나 내가 갇혀지기 시작하고 곳은 내가리플렉션을 사용하여 일반/동적 linq 조건 자의 하위 속성 비교

public class Parent { 
    public virtual Child child { get; set; } 
    .... Other Stuff... 
} 

public class Child { 
    public int property { get; set; } 
    public virtual Parent parent { get; set; } 
    .... Other Stuff..... 
} 

어떻게 내가 반사로 "Child.property"에 전달할 수 있습니다 관계를 비교하는 람다 식을 작성하고 올 할 수 있도록이있는 법인을 가지고있다 item => item.Child.property == value와 비슷한 람다 식을 사용합니다.

답변

3

난 당신이 찾고있는 생각 :

ParameterExpression parameter = Expression.Parameter(typeof(Parent), "item"); 
Expression child = Expression.PropertyOrField(parameter, "child"); 
Expression childProperty = Expression.PropertyOrField(child, "property"); 
int value = 1; 
Expression comparison = Expression.Equal(childProperty, Expression.Constant(value)); 

Expression<Func<Parent, bool>> lambda = Expression.Lambda<Func<Parent, bool>>(comparison, parameter); 


var sample = new[] { new Parent() { child = new Child() { property = 1 } } }; 
var result = sample.Where(lambda.Compile()); 
3

난 당신이 중첩 된 속성을 지원하는 일반적인 솔루션을 원하고 있다고 가정합니다 :

public Expression buildLambda(Type startingType, string propertyPath, object value) { 

    var parameter=Expression.Parameter(startingType,"item"); 
    var valueExpression = Expression.Constant(value); 
    var propertyExpression=propertyPath.Split('.').Aggregate(parameter,(Expression parent,string path)=>Expression.Property(parent,path)); 
    return Expression.Lambda(Expression.Equal(propertyExpression,valueExpression),parameter); 
} 
+0

이 작동합니다. 컬렉션에 대해 어떻게 처리합니까? – Kenci

+0

@Kenci와 마찬가지로 속성 색인 생성을 사용합니까? 'Wibble [5] .Value' –

+0

OP의 Child 속성이 컬렉션 인 경우 람다가 다음과 같이 될 수 있도록 해당 컬렉션 주위에 "contains"를 포함하고 싶습니다. Parent.Where (x = > someList.Contains (x.property); – Kenci