簡體   English   中英

LINQ中類似對象的動態表達

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM