LINQ to Entities does not recognize the method Gen

2019-02-24 20:08发布

问题:

The database contains Orders. Orders can be contained within a group of Orders. For every group of Orders it could contain 1 to many Orders.

However, Orders could have a NULL value assigned GroupOrderId as previous Orders did not have the grouping concept. Only new Orders enforce the concept of being added to a group.

The class structure to be populated in order to perform actions on each Order is

public class OrdersGroup
{
    public int? GroupOrderId { get; set; }
    public List<int> OrderIds { get; set; }
}

The linq statement

var workPacketOrdersList = (from o in db.Orders
                                    where
                                        o.GroupOrderId >= groupOrderIdMin && o.GroupOrderId <= groupOrderIdMax &&
                                        o.IsDeleted == false
                                    orderby o.WorkPacketId ascending
                                    group o by o.WorkPacketId
                                    into grp
                                    select new OrdersGroup
                                               {
                                                   GroupOrderId = grp.Key,
                                                   OrderIds = grp.Select(g => g.OrderId).ToList()
                                               }).ToList();

Full exception

LINQ to Entities does not recognize the method 'System.Collections.Generic.List`1[System.Int32] ToList[Int32](System.Collections.Generic.IEnumerable`1[System.Int32])' method, and this method cannot be translated into a store expression.

I see that the returned type of the linq query is a List<OrdersGroup>.

If the final .ToList() is omitted from the query than the return type becomes an IQueryable<OrdersGroup>

No matter what action is performed next the result is an exception that this method cannot be translated into a store expression.

I have tried to remove the specific select new OrdersGroup into a more generic select new and then perform actions on this result only to find the same store expression exception.

Can someone give some insight into where this linq is incorrect?

回答1:

this is the part that's failing - grp.Select(g => g.OrderId).ToList() - you can't have a .ToList() in the select clause. remove that and you should be fine.



回答2:

The problem is that LINQ to Entities is attempting to convert your query into SQL. It doesn't know how translate ToList into SQL, so that's the problem. You need to remove the call to ToList from inside your query.

That is,

OrderIds = grp.Select(g => g.OrderId).ToList()

LINQ to Entities can not convert that to SQL. Remove the call

OrderIds = grp.Select(g => g.OrderId)

and if you need OrderIds to be a List<int>, do the call to ToList after you execute the query.



回答3:

It's because you're trying to call ToList() in a part of the query that will become raw SQL and executed at the source (ie SQL Server, not the CLR). I don't know exactly what your data is so I can't necessarily make an accurate recommendation on how to fix it but I would try taking making the ToList() call after this query or just not making it all. It's likely IEnumberable will offer whatever functionality you need which is what the Select will return if you remove the ToList() call.

By the way since I wasn't explicit, I'm referring to the ToList() call inside the select -(second to last line) OrderIds = grp.Select(g => g.OrderId).ToList() the other one is fine. It's executed on the results of the SQL query which is perfectly fine, you just can't make calls to C# specific methods within a query that will be executed by the SQL provider.



回答4:

Your problem is that you select a list in your select statement.

select new OrdersGroup
{
   GroupOrderId = grp.Key,
   OrderIds = grp.Select(g => g.OrderId).ToList()
   /////////////////////////////////////^^^^^^^^^HERE
}

What you need to do is change OrderIds to an IEnumerable<int>, and then get rid of the ToList.