Search code examples
linqentity-frameworklinq-to-entitiesexpressiondeferred-execution

Entity Framework Execute Expression


Here is simplified code

from oi in orderItems
    group oiGrouped by ...
    into orderItemsGroupedBySomething
    select new
    {
        Key = orderItemsGroupedBySomething.Key,

        Revenue = /*Here is some code that I want to extract to separate method, for example*/ 
            orderItemsGroupedBySomething.Sum(x => x.UnitPrice * x.Quantity)                     
    }

Actually it's more complex in my case. But I think it doesn't matter. I'm not able to extract to simple method calculation of orderItemsGroupedBySomething.Sum(x => x.UnitPrice * x.Quantity) because it's not known method for EntityFramework. I tried put it to expression but I get error "The LINQ expression node type 'Invoke' is not supported in LINQ to Entities." I compiled expression before use it in query, I think therefore I get error. How can I solve this problem?


Solution

  • I added method that return expression

    public Expression<Func<OrderItem, decimal>> GetExpression()
    {
        return x => x.UnitPrice*x.Quantity;
    }
    

    Then I tried

    from oi in orderItems
        group oiGrouped by ...
        into orderItemsGroupedBySomething
        select new
        {
            Key = orderItemsGroupedBySomething.Key,
            Revenue =  orderItemsGroupedBySomething.Sum(GetExpression())                     
        }
    

    But it doesn't work such as with @LorentzVedeler answer. Because orderItemsGroupedBySomething is of type IGrouping that don't have Sum method with param of type Expression. Therefore I tried

    orderItemsGroupedBySomething.AsQueryable.Sum(GetExpression())
    

    But it causes Internal .NET Framework Data Provider error 1025. The issue was that I invoked method GetExpression() in linq. To solve this problem I put expression to local variable. The result

    var expression = GetExpression();
    
    from oi in orderItems
            group oiGrouped by ...
            into orderItemsGroupedBySomething
            select new
            {
                Key = orderItemsGroupedBySomething.Key,
                Revenue =  orderItemsGroupedBySomething.AsQueryable.Sum(expression)                     
            }