使用通用类型列表对数据进行分组

时间:2013-11-18 08:17:13

标签: c# .net linq entity-framework linq-to-entities

我有列表数据(不知道指定的类型)和属性名称(在字符串中)。如何根据属性名称对列表数据进行分组?

1 个答案:

答案 0 :(得分:0)

当类型完全未知时(即它不仅仅是通用函数中的List)

,此解决方案将起作用

这是带有效用函数的助手类。

public static class HelperClass {
  public static object GetProperty(this object source, string name) {
     if (source == null) return null;
     var pi = source.GetType().GetProperty(name);
     if (pi == null) return null;
     return pi.GetValue(source);
  }
}

现在假设您的列表数据位于名为myList的变量中,且属性名称位于name中:

var groupedResults = myList.Cast<object>().GroupBy(x => x.GetProperty(name));

Cast()确保您使用的是IEnumerable,其中T是对象,以便GroupBy扩展名可以正常工作。

但是,如果您使用List<T>进行操作,其中特定T是一般参数(即您不知道Tstring但是你知道它的泛型参数T还有可以使用表达式构建的替代解决方案。这将允许你使用IQueryables,它应该正确地对你支持的sql源进行翻译。

static class HelperClass {

  static Expression<Func<T,object>> GroupByExpression<T>(string propertyName) {
    var parameter = Expression.Parameter(typeof(T),"x");
    var body =  Expression.Property(parameter,propertyName);
    return Expression.Lambda<Func<T,object>>(Expression.Convert(body, typeof(object)), parameter);
  }
}

现在可以同时使用IQuerable<T>IList<T>

所以如果你在T匹配T IList<T>的通用函数中,你可以使用

其中myListIQueryable<T>

myList.GroupBy(HelperClass.GroupByExpression<T>(name))

以及myListIList<T>IEnumerable<T>

的位置
myList.GroupBy(HelperClass.GroupByExpression<T>(name).Compile())