I tried to answer this question but failed:
So let's take the original query:
var result = db.Employees.GroupBy(x => x.Region)
.Select(g => new { Region = g.Key,
Avg = g.Average(x => x.BaseSalary)});
Works fine. Now we want to dynamically decide what to average. I try to create the lambda for Average
dynamically:
string property = "BaseSalary";
var parameter = Expression.Parameter(typeof(Employee));
var propAccess = Expression.PropertyOrField(parameter, property);
var expression = (Expression<Func<Employee,int?>>)Expression.Lambda(propAccess, parameter);
var lambda = expression.Compile();
and use it:
var result = db.Employees.GroupBy(x => x.Region)
.Select(g => new { Region = g.Key,
Avg = g.Average(lambda)});
With Linq2Sql this results in a NotSupportedException
:
Für den Abfrageoperator "Average" wurde eine nicht unterstützte Überladung verwendet.
(I only have the German error message, it says that the used overload of Average
is not supported, feel free to edit if you have the English version).
The original question used Linq2Entities and got the error
Internal .NET Framework Data Provider error 102
IntelliSense (or some other IDE feature) tells me that in both versions the compiler chooses the same overload of Average
:
double? Enumerable.Average(this IEnumerable<Employee> source, Func<Employee, int?> selector);
And I rechecked with an ExpressionVisitor
that my lambda
is exactly the same expression as x => x.BaseSalary
.
So: Why it suddenly isn't supported anymore?
Interesting: there is no such exception if I don't group and use it simply like:
double? result = db.Employees.Average(lambda);
With YuvalShap's answer I also tried Avg = g.AsQueryable().Average(expression)
(using an expression instead of the lambda), but with the same result.