如何使用动态LINQ进行求和

我有以下与动态linq库完美配合:

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

现在我想查询MyDataQueryable来执行某些字段的SUM(也许是平均值)。

我怎么会这样呢?

就像是:

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

会好的…

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

 var myDataQueryable = _DataRawBase.AsQueryable() .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(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); } 

这段代码对我有用:

浮动? fSum = qryQueryableData.Select(“Price”)。Cast ()。Sum();

“价格”是“浮动”类型的列?

这里有解释。

我需要扩展Caramiriel的处理字段的答案:

  public static object Sum(this IQueryable source, string member) { if (source == null) throw new ArgumentNullException("source"); if (member == null) throw new ArgumentNullException("member"); // Properties PropertyInfo property = source.ElementType.GetProperty(member); FieldInfo field = source.ElementType.GetField(member); ParameterExpression parameter = Expression.Parameter(source.ElementType, "s"); Expression selector = Expression.Lambda(Expression.MakeMemberAccess(parameter, (MemberInfo)property ?? field), parameter); // We've tried to find an expression of the type Expression>, // which is expressed as ( (TSource s) => s.Price ); // Method MethodInfo sumMethod = typeof(Queryable).GetMethods().First( m => m.Name == "Sum" && (property != null || field != null) && (property == null || m.ReturnType == property.PropertyType) // should match the type of the property && (field == null || m.ReturnType == field.FieldType) // should match the type of the property && m.IsGenericMethod); return source.Provider.Execute( Expression.Call( null, sumMethod.MakeGenericMethod(new[] { source.ElementType }), new[] { source.Expression, Expression.Quote(selector) })); } 

尝试使用lambda表达式:

 double mysum = MyDataQueryable.Sum(mdq => mdq.Price);