Click here to Skip to main content
15,948,339 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
hi everyone,
iam working on a project where iam using devexpress mvc gridview & iam trying to group rows
here's my code

C#
public static object Sum(this IQueryable query, string fieldName)
        {
            if (query.Count() == 0)
                return 0;

            var parameter = Expression.Parameter(query.ElementType, string.Empty);
            var propertyInfo = query.ElementType.GetProperty(fieldName);
            var propertyAccess = Expression.MakeMemberAccess(parameter, propertyInfo);
            var propertyAccessExpression = Expression.Lambda(propertyAccess, parameter);
            var expression = Expression.Call(
                typeof(Queryable),
                "Sum",
                new Type[] { query.ElementType },
                query.Expression,
                Expression.Quote(propertyAccessExpression)
            );
            return query.Provider.Execute(expression);
        }



but here the error i got :

No generic method 'Sum' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic.


plz anyone have the same situation &got a solution would tell me what's the wrong

thanks in advance
Posted

1 solution

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:
C#
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); // Returns null if the type is not Nullable<T>

switch (Type.GetTypeCode(baseType ?? propertyType))
{
    case TypeCode.Int32:
    case TypeCode.Int64:
    case TypeCode.Single:
    case TypeCode.Double:
    case TypeCode.Decimal:
    {
        // Supported type - use the property directly:
        body = propertyAccess;
        break;
    }
    case TypeCode.Byte:
    case TypeCode.SByte:
    case TypeCode.Int16:
    case TypeCode.UInt16:
    {
        // Small enough to fit in an Int32:
        Type targetType = typeof(int);
        if (baseType != null) targetType = typeof(Nullable<>).MakeGenericType(targetType);
        body = Expression.Convert(propertyAccess, targetType);
        break;
    }
    case TypeCode.UInt32:
    {
        // Convert to an Int64:
        Type targetType = typeof(long);
        if (baseType != null) targetType = typeof(Nullable<>).MakeGenericType(targetType);
        body = Expression.Convert(propertyAccess, targetType);
        break;
    }
    default:
    {
        // Unknown type - try converting to Double.
        // If there is no conversion, this will throw an exception.
        
        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.
 
Share this answer
 
Comments
eso0o 27-Jan-15 2:38am    
actually the field name iam passing is datetime type , so that was the problem ???
Richard Deeming 27-Jan-15 7:24am    
Yes, summing a DateTime property doesn't make any sense. What would you expect the result of 2014/12/31 + 2015/01/27 to be? :)
eso0o 27-Jan-15 2:41am    
i just changed the field type to be a type of int ,thanks soooo much for ur helpful response :)
eso0o 28-Jan-15 6:03am    
that is what i told myself after ur answer i guess i wasn't focusing enough

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900