The
fieldName
you've passed in doesn't represent a property with one of the supported types:
int
/ Nullable<int>
long
/ Nullable<long>
float
/ Nullable<float>
double
/ Nullable<double>
decimal
/ Nullable<decimal>
Those are the only types which can be processed by the
Sum
method. For any other property type, you'll need to convert the property value to a suitable type.
Something like this should work:
var parameter = Expression.Parameter(query.ElementType, string.Empty);
var propertyInfo = query.ElementType.GetProperty(fieldName);
var propertyAccess = Expression.MakeMemberAccess(parameter, propertyInfo);
Expression body;
Type propertyType = propertyAccess.Type;
Type baseType = Nullable.GetUnderlyingType(propertyType);
switch (Type.GetTypeCode(baseType ?? propertyType))
{
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Single:
case TypeCode.Double:
case TypeCode.Decimal:
{
body = propertyAccess;
break;
}
case TypeCode.Byte:
case TypeCode.SByte:
case TypeCode.Int16:
case TypeCode.UInt16:
{
Type targetType = typeof(int);
if (baseType != null) targetType = typeof(Nullable<>).MakeGenericType(targetType);
body = Expression.Convert(propertyAccess, targetType);
break;
}
case TypeCode.UInt32:
{
Type targetType = typeof(long);
if (baseType != null) targetType = typeof(Nullable<>).MakeGenericType(targetType);
body = Expression.Convert(propertyAccess, targetType);
break;
}
default:
{
Type targetType = typeof(double);
if (baseType != null) targetType = typeof(Nullable<>).MakeGenericType(targetType);
body = Expression.Convert(propertyAccess, targetType);
break;
}
}
var propertyAccessExpression = Expression.Lambda(body, parameter);
var expression = Expression.Call(
typeof(Queryable),
"Sum",
new Type[] { query.ElementType },
query.Expression,
Expression.Quote(propertyAccessExpression)
);
return query.Provider.Execute(expression);
Also, there is no built-in
Count
extension method for the non-generic
IQueryable
interface. Unless you've created your own, or imported a third-party version, the first line of your method won't work.