2017-02-12 66 views
0

我有一個稱爲FindAll()的服務方法,它需要一個表達式/謂詞參數並返回所有匹配的行。LINQ for Similar Objects中的動態表達式

比方說,我有一個Book對象的集合,並且我想要獲取所有在字符串列表中找到的名稱的書籍。我想有這樣的事情:

var lstNames = { "Book1", "Book2" }; 
var matchedBooks = myService<Book>.FindAll(x => lstNames.Any(y => x.Name.Equals(y))); 

我也有一些其他類,都具有Name財產,所以我想建立一個動態表情,讓我做這樣的事情:

var matchedObjs = myService<T>.FindAll(x => lstNames.Any(y => x.Name.Equals(y))); 

我該如何構建這樣的動態表達式?

+1

要麼使用接口,要麼使用動態變量 – Jbjstam

+0

也不想做。 EF生成這些類,即使可以,也不想在其上添加接口。創建一個動態表達式似乎是最乾淨的方式。 – notlkk

+0

你使用FindAll而不是Where的原因是什麼? – Abion47

回答

0

多虧了這樣的回答:How to declare a Linq Expression variable in order to have it processed as a dbParameter

我建議你這樣做:

static Expression<Func<T, bool>> GetExpr<T> (string name, string value) 
{ 
    ParameterExpression param = Expression.Parameter(typeof(T), "x"); 
    Expression prop = Expression.Property(param, name); // this is the property name, e.g. .Name 
    Expression<Func<string>> valueLambda =() => value; // This is the value for == expression. 
    Expression lookupExpression = Expression.Equal(prop, valueLambda.Body); 

    Expression<Func<T, bool>> expr = Expression.Lambda<Func<T, bool>>(lookupExpression, param); 

    return expr; 
} 

...或者,對。載有():

static Expression<Func<T, bool>> GetExprContains<T>(string name, string[] value) 
{ 
    ParameterExpression param = Expression.Parameter(typeof(T), "x"); 
    Expression prop = Expression.Property(param, name); // this is the property name, e.g. .Name 
    Expression<Func<string[]>> valueLambda =() => value; // This is the value for .Contains() expression. 
    var mi = 
    typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public) 
     .FirstOrDefault(x => x.Name == "Contains" && x.GetParameters().Count() == 2) 
     .MakeGenericMethod(typeof(string)); // Need methodinfo for .Contains(), might want to keep static somewhere 
    var lookupExpr = Expression.Call(null, mi, valueLambda.Body, prop); 

    Expression<Func<T, bool>> expr = Expression.Lambda<Func<T, bool>>(lookupExpr, param); 

    return expr; 
} 

測試,可與EF 。