问题描述
这个问题在此指的是我以前的问题在这里
@xanatos建议的sum()表达式完美.
我还尝试了double类型字段的max()表达式,并且没有问题.
作为下一步,我决定添加DateTime字段并为其计算Max().
我修改了组类,如下:
private class GroupSum : GroupKey { public Double AggN0 { get; set; } public DateTime AggD0 { get; set; } }
并编程了功能:
private static Func<IGrouping<GroupKey, DataRow>, DateTime> GetFuncMaxDateTime() { MethodInfo methInfo = typeof(DataRowExtensions).GetMethod("Field", new Type[] { typeof(DataRow), typeof(string) }); ParameterExpression expRow = Expression.Parameter(typeof(DataRow), "row"); //Parametr: (row =>....) PropertyInfo propertyInfo = typeof(GroupSum).GetProperty("AggD0"); MethodCallExpression expCall = GetFieldCallExpression(expRow, methInfo, propertyInfo.PropertyType, "DocumentDate"); var expRowValues = Expression.Lambda(expCall, expRow); ParameterExpression expQuerygroup = Expression.Parameter(typeof(IGrouping<GroupKey, DataRow>), "g"); //HERE it throws an error: No generic method 'Max' on type 'System.Linq.Enumerable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic. MethodCallExpression expMaxRows = Expression.Call(typeof(Enumerable), "Max", new[] { expRow.Type }, expQuerygroup, expRowValues); var max = Expression.Lambda<Func<IGrouping<GroupKey, DataRow>, DateTime>>(expMaxRows, expQuerygroup); return max.Compile(); }
代码编译,但在运行时会引发错误.我评论了该说明并指定了错误消息.
这很奇怪,因为唯一的区别是
double sum(double)
vs
DateTime Max(DateTime)
无需添加硬编码版本正常.
private static IEnumerable<GroupSum> GetListOfGroupedRows(IEnumerable<IGrouping<GroupKey, DataRow>> queryGroup) { IEnumerable<GroupSum> querySelect = queryGroup .Select(g => new GroupSum { KeyS0 = g.Key.KeyS0, KeyS1 = g.Key.KeyS1, AggN0 = g.Sum(row => row.Field<double>("Amount")), AggD0 = g.Max(row => row.Field<DateTime>("DocumentNumber")) }); return querySelect; }
推荐答案
更改此行添加expRowValues.ReturnType:
MethodCallExpression expMaxRows = Expression.Call( typeof(Enumerable), nameof(Enumerable.Max), new[] { expRow.Type, expRowValues.ReturnType }, expQuerygroup, expRowValues);
因为您想要这个过载:
public static TResult Max<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector);
so 两个通用类型参数!
问题描述
The question hereby refers to my previous question here
The Sum() expression advised by @xanatos worked perfectly.
I tried also Max() expression for the field of the type double and faced no issue.
As the next step I decided to add the DateTime field and calculate Max() for it.
I modified the GroupSum class as follows:
private class GroupSum : GroupKey { public Double AggN0 { get; set; } public DateTime AggD0 { get; set; } }
And programmed the function:
private static Func<IGrouping<GroupKey, DataRow>, DateTime> GetFuncMaxDateTime() { MethodInfo methInfo = typeof(DataRowExtensions).GetMethod("Field", new Type[] { typeof(DataRow), typeof(string) }); ParameterExpression expRow = Expression.Parameter(typeof(DataRow), "row"); //Parametr: (row =>....) PropertyInfo propertyInfo = typeof(GroupSum).GetProperty("AggD0"); MethodCallExpression expCall = GetFieldCallExpression(expRow, methInfo, propertyInfo.PropertyType, "DocumentDate"); var expRowValues = Expression.Lambda(expCall, expRow); ParameterExpression expQuerygroup = Expression.Parameter(typeof(IGrouping<GroupKey, DataRow>), "g"); //HERE it throws an error: No generic method 'Max' on type 'System.Linq.Enumerable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic. MethodCallExpression expMaxRows = Expression.Call(typeof(Enumerable), "Max", new[] { expRow.Type }, expQuerygroup, expRowValues); var max = Expression.Lambda<Func<IGrouping<GroupKey, DataRow>, DateTime>>(expMaxRows, expQuerygroup); return max.Compile(); }
The code compiles but it throws an error at runtime. I commented the instruction and specified the error message.
It is strange because the only difference is
double Sum(double)
vs
DateTime Max(DateTime)
No need to add that hardcoded version works ok.
private static IEnumerable<GroupSum> GetListOfGroupedRows(IEnumerable<IGrouping<GroupKey, DataRow>> queryGroup) { IEnumerable<GroupSum> querySelect = queryGroup .Select(g => new GroupSum { KeyS0 = g.Key.KeyS0, KeyS1 = g.Key.KeyS1, AggN0 = g.Sum(row => row.Field<double>("Amount")), AggD0 = g.Max(row => row.Field<DateTime>("DocumentNumber")) }); return querySelect; }
推荐答案
Change this line adding expRowValues.ReturnType:
MethodCallExpression expMaxRows = Expression.Call( typeof(Enumerable), nameof(Enumerable.Max), new[] { expRow.Type, expRowValues.ReturnType }, expQuerygroup, expRowValues);
because you want this overload:
public static TResult Max<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector);
so two generic type parameters!