c# - 如何使用 Dynamic LINQ 求和

标签 c# linq

我有以下与 dynamic linq library 一起出色工作的:

string where = "Price < 5";
string orderby = "BookID ASC";
IQueryable<T> MyDataQueryable = _DataRawBase.AsQueryable<T>();
MyDataQueryable = MyDataQueryable.Where(where).OrderBy(orderby);

现在我想查询 MyDataQueryable 以对某些字段求和(也许求平均值)。

我该怎么做?

类似于:

double mysum = MyDataQueryable.Sum("Price");  

会很好...

最佳答案

由于所有内容都是字符串类型,您可能想尝试:

var myDataQueryable = _DataRawBase.AsQueryable<T>()
    .Sum("Price");

使用以下扩展方法:

public static object Sum(this IQueryable source, string member)
{
    if (source == null) throw new ArgumentNullException(nameof(source));
    if (member == null) throw new ArgumentNullException(nameof(member));

    // The most common variant of Queryable.Sum() expects a lambda.
    // Since we just have a string to a property, we need to create a
    // lambda from the string in order to pass it to the sum method.

    // Lets create a ((TSource s) => s.Price ). First up, the parameter "s":
    ParameterExpression parameter = Expression.Parameter(source.ElementType, "s");

    // Followed by accessing the Price property of "s" (s.Price):
    PropertyInfo property = source.ElementType.GetProperty(member);
    MemberExpression getter = Expression.MakeMemberAccess(parameter, property);

    // And finally, we create a lambda from that. First specifying on what
    // to execute when the lambda is called, and finally the parameters of the lambda.
    Expression selector = Expression.Lambda(getter, parameter);

    // There are a lot of Queryable.Sum() overloads with different
    // return types  (double, int, decimal, double?, int?, etc...).
    // We're going to find one that matches the type of our property.
    MethodInfo sumMethod = typeof(Queryable).GetMethods().First(
        m => m.Name == "Sum"
             && m.ReturnType == property.PropertyType
             && m.IsGenericMethod);

    // Now that we have the correct method, we need to know how to call the method.
    // Note that the Queryable.Sum<TSource>(source, selector) has a generic type,
    // which we haven't resolved yet. Good thing is that we can use copy the one from
    // our initial source expression.
    var genericSumMethod = sumMethod.MakeGenericMethod(new[] { source.ElementType });

    // TSource, source and selector are now all resolved. We now know how to call
    // the sum-method. We're not going to call it here, we just express how we're going
    // call it.
    var callExpression = Expression.Call(
        null,
        genericSumMethod,
        new[] {source.Expression, Expression.Quote(selector)});

    // Pass it down to the query provider. This can be a simple LinqToObject-datasource,
    // but also a more complex datasource (such as LinqToSql). Anyway, it knows what to
    // do.
    return source.Provider.Execute(callExpression);
}

关于c# - 如何使用 Dynamic LINQ 求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17490080/

相关文章:

c# - 两个字符整数到字符?

c# - 为最小 int 值设置约束

linq - 如何将 LINQ 查询结果转换为 List?

c# - Linq 进行非常低效的 Entity Framework 查询

.net - ObservableCollection 更改时重新评估 LINQ 查询

C#配置管理器。连接字符串

c# - 使用 C# 学习多线程的资源

c# - 如何将 List<KeyValuePair<int,int>> 转换为 int[][]?

linq - Groovy 和 LINQ 之间有哪些相同点和不同点?

c# - 如何为 EPPlus 中的字体指定颜色?