[英]Dynamic Expression in LINQ for Similar Objects
我有一個稱為FindAll()的服務方法,該方法需要一個表達式/謂詞參數並返回所有匹配的行。
假設我有一個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)));
如何構建這樣的動態表達?
感謝此答案: 如何聲明Linq Expression變量以將其作為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;
}
...或者對於.Contains():
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搭配使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.