2012-11-05 57 views
3

我必須一般地爲實體框架Linq查詢構建一個比較謂詞。我正在使用反射,並且能夠毫無困難地構建單個級別的Lambda表達式。然而,當我開始卡住是我有了一個關係在反射中使用泛型/動態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」到反思能夠創建一個lambda表達式比較,並拿出一個實體用lambda表達式類似於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」,這樣你的lambda會像這樣:Parent.Where(x = > someList.Contains(x.property); – Kenci