IQueryable.GroupBy覆盖抛出int和布尔值,但不是字符串
我有一个IQueryable的扩展方法的第一个草案与GroupBy应该由命名属性分组的覆盖。IQueryable.GroupBy覆盖抛出int和布尔值,但不是字符串
在问你之前,我没有使用动态表达式API(又名动态Linq),因为我无法弄清楚如何通过它访问每个组的计数。该库中的GroupBy方法返回一个非通用的IQueryable
,而不是我需要的一个IQueryable<IGrouping<>>
。如果有办法通过图书馆了解统计数字,我会很乐意接受一个答案,告诉我如何。也许某种语法,我找不到string elementSelector
参数中的文档?
代码:
public static IQueryable<IGrouping<object, T>> GroupBy<T>(this IQueryable<T> source, string propertyName)
{
ParameterExpression param = Expression.Parameter(typeof(T), String.Empty);
MemberExpression property = Expression.PropertyOrField(param, propertyName);
LambdaExpression group = Expression.Lambda(property, param);
MethodCallExpression call = Expression.Call(
typeof(Queryable),
"GroupBy",
new[] { typeof(T), property.Type },
source.Expression,
Expression.Quote(group));
return source.Provider.CreateQuery<IGrouping<object, T>>(call);
}
我使用它是这样的:
public IEnumerable<Category> GetCategories(IQueryable<T> entities, string property)
{
var haba = entities.GroupBy(property);
var categories = haba.Select(group => new Category(group.Key.ToString(), group.Count()));
return categories.ToArray();
}
而且只要我的属性是字符串类型的它workes罚款。但是,如果我试图把它用在一个int或布尔财产,我得到类似如下的错误在电话会议中的createQuery:
参数表达的类型为 System.Linq.IQueryable
1[System.Linq.IGrouping
2 System.Int32, DerivedEntity1]] 当类型 System.Collections.Generic.IEnumerable1[System.Linq.IGrouping
2 [System.Object,DerivedEntity1]] 预计。参数名:表达
我注意到,它的预期的IEnumerable
通用的,而不是一个IQueryable
,这很奇怪。但是一个很好的提示。您无法将IEnumerable
投射到IQueryable
而不执行AsQueryable()
。那么问题是,为什么它给我一个IEnumerable
而不是IQueryable
?为什么当我传递一个字符串属性的propertyName时,它不会以相同的方式失败?
我应该提一下,我的IQueryable
的实例是来自NHibernate的NhQueryable
,也就是说。
我觉得从值类型拳击是从您的代码丢失:
public static IQueryable<IGrouping<object, T>> GroupBy<T>(this IQueryable<T> source, string propertyName)
{
ParameterExpression param = Expression.Parameter(typeof(T), String.Empty);
MemberExpression property = Expression.PropertyOrField(param, propertyName);
UnaryExpression convert = Expression.Convert(property, typeof(object));
LambdaExpression group = Expression.Lambda(convert, param);
MethodCallExpression call = Expression.Call(
typeof(Queryable),
"GroupBy",
new[] { typeof(T), typeof(object) },
source.Expression,
Expression.Quote(group));
return source.Provider.CreateQuery<IGrouping<object, T>>(call);
}
你有没有试图改变你的方法定义,包括其他泛型类型,像这样
public static IQueryable<IGrouping<O, T>> GroupBy<O, T>(this IQueryable<T> source, string propertyName)
{
return source.Provider.CreateQuery<IGrouping<O, T>>(call);
}
消耗它像:
var haba = entities.GroupBy<int, Category>(property);
不起作用,因为我将不得不在运行时通过T上的反射来推测O类型ertyName。泛型需要在编译时确定。除非我错过了什么..? – Mithon 2012-03-19 18:06:46
@Mithon - 你不需要在运行时做任何事情。您正在编译时指定类型。 * entities.GroupBy
no .. cause有时propertyName将对应于O = string类型的属性,有时O = int,有时O = DateTime等等等等。关于我发送的一个字符串,它传递给一个传递名为propertyName的字符串的web服务。 – Mithon 2012-03-19 21:42:27
这就像一个魅力。非常感谢你! :) – Mithon 2012-03-20 08:20:12
相当有用的感谢 – 2017-09-29 13:07:51