1

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?

Daniil Grankin
  • 3,841
  • 2
  • 29
  • 39

2 Answers2

1

I don't know how generic you need it to be, but something like this should work:

void Main()
{
    OrderItems.GroupBy(oi => oi.SomeProp).Select(GetExpression());
}

public Expression<Func<IGrouping<KeyType, OrderItem>, dynamic>> GetExpression()
{
    return (ig) => new { Key = ig.Key, Revenue = ig.Sum(x => x.UnitPrice * x.Quantity) };
}

edit: In the case of a grouping, I would probably return a Tuple in stead of an anonymous type.

Lorentz Vedeler
  • 5,101
  • 2
  • 29
  • 40
  • thank you. I'm not able to use lamda syntax. I tried it without lamda syntax and `select GetExpression()` the statement return `Expression, dynamic>>` I can use fields of dynamic in next queries. – Daniil Grankin Mar 19 '14 at 10:00
  • And also for me it's not suitable to put all select to expression. I want to share some expressions and use it in different places. – Daniil Grankin Mar 19 '14 at 10:01
1

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)                     
        }
Daniil Grankin
  • 3,841
  • 2
  • 29
  • 39
  • Very helpful. The strange thing for me was that the query didnt require the expression to be a local variable unless the expression was being used in a subselect of a group by. Very strange. – johnnywhoop Jul 10 '14 at 18:37
  • @johnnywhoop, If I get you correctly, I think the thing about local variable related with fact that query can be not linq to entity nor linq to sql, it can be for example linq to object in this cases it would not require local variable – Daniil Grankin Jul 10 '14 at 22:02