LINQ Dynamic Expression Call the Count() method on a List property

旧巷老猫 提交于 2021-01-28 09:24:02

问题


Using LINQ Expression dynamic need to call the list Count() method.

 public class Foo
 {
      public int Id { get; set; }
 }

 public class Bar
 {
      public ICollection<Foo> Data { get; set; }
 }

 var list = new List<Bar>();

Need to build a predicate dynamically which can return me the list of Bar which have Data.Count() > 1 using Expressions.

To start off something like this..

MethodInfo method = typeof(Enumerable).GetMethods()
.Where(m => m.Name == "Count" && m.GetParameters().Length == 2).Single().MakeGenericMethod(typeof(Bar));

回答1:


The Count method you are looking for has only 1 parameter:

public static int Count<TSource>(this IEnumerable<TSource> source)

You could also use the Count property since the source is an ICollection:

//build a lambda: (Bar bar) => bar.Data.Count > 1;
var barParam = Expression.Parameter(typeof (Bar), "bar");
var barDataProperty = Expression.PropertyOrField(barParam, "Data");
//since Data is of type ICollection, we can use the Count Property
var count = Expression.PropertyOrField(barDataProperty, "Count");
//if you do not want this dependency, call the Count() extension method:
var enumerableCountMethod = typeof (Enumerable).GetMethods()
    .First(method => method.Name == "Count" && method.GetParameters().Length == 1)
    .MakeGenericMethod(typeof(Foo));
var count2 = Expression.Call(enumerableCountMethod, barDataProperty);

var comparison = Expression.GreaterThan(count, Expression.Constant(1));
var comparison2 = Expression.GreaterThan(count2, Expression.Constant(1));

Expression<Func<Bar, bool>> expr = Expression.Lambda<Func<Bar, bool>>(comparison, barParam);
Expression<Func<Bar, bool>> expr2 = Expression.Lambda<Func<Bar, bool>>(comparison2, barParam);

var list = new List<Bar>();
var filteredList = list.Where(expr.Compile());
var filteredList2 = list.Where(expr2.Compile());



回答2:


You could probably use the predicate builder. For example:

IQueryable<Product> SearchProducts (params string[] keywords)
{
  var predicate = PredicateBuilder.False<Product>();

  foreach (string keyword in keywords)
  {
    string temp = keyword;
    predicate = predicate.Or (p => p.Description.Contains (temp));
  }
  return dataContext.Products.Where (predicate);
}


来源:https://stackoverflow.com/questions/31251571/linq-dynamic-expression-call-the-count-method-on-a-list-property

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!