LINQ to Entities 无法识别 Generic.List(int) 到 Generic.IEnumerable(int) 方法

问题描述 投票:0回答:4

数据库包含订单。 订单可以包含在一组订单中。 对于每组订单,它可以包含 1 到多个订单。

但是,订单可以为 GroupOrderId 分配 NULL 值,因为之前的订单没有分组概念。只有新订单才会强制执行添加到组中的概念。

为了对每个订单执行操作而要填充的类结构是

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

linq 语句

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();

完全例外

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.

我看到 linq 查询的返回类型是

List<OrdersGroup>

如果查询中省略了最后的 .ToList(),则返回类型将变为

IQueryable<OrdersGroup>

无论接下来执行什么操作,结果都是异常,该方法无法转换为存储表达式。

我尝试将特定的

select new OrdersGroup
删除为更通用的
select new
,然后对此结果执行操作,却发现相同的商店表达式异常。

有人可以深入了解这个 linq 哪里不正确吗?

c# .net linq .net-4.0 linq-to-entities
4个回答
11
投票

这是失败的部分 -

grp.Select(g => g.OrderId).ToList()
- select 子句中不能有 .ToList() 。删除它,你应该没问题。


7
投票

问题在于 LINQ to Entities 正在尝试将您的查询转换为 SQL。它不知道如何将

ToList
翻译成 SQL,所以这就是问题所在。您需要从查询中删除对
ToList
的调用。

也就是说,

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

LINQ to Entities 无法将其转换为 SQL。删除通话

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

如果您需要

OrderIds
成为
List<int>
,请在执行查询后调用
ToList


3
投票

您的问题是您在 select 语句中选择了一个列表。

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

您需要做的就是将

OrderIds
更改为
IEnumerable<int>
,然后去掉
ToList


2
投票

这是因为您尝试在查询的一部分中调用

ToList()
,该查询将成为原始 SQL 并在源(即 SQL Server,而不是 CLR)执行。我不知道你的数据到底是什么,所以我不一定能就如何修复它提出准确的建议,但我会尝试在此查询后进行
ToList()
调用,或者只是不进行全部操作。
IEnumerable
可能会提供您需要的任何功能,如果您删除
Select
调用,
ToList()
将返回该功能。

顺便说一句,因为我没有明确表示,我指的是 select 中的

ToList()
调用 -(倒数第二行)
OrderIds = grp.Select(g => g.OrderId).ToList()
另一个很好。它是在 SQL 查询的结果上执行的,这完全没问题,只是您无法在将由 SQL 提供程序执行的查询中调用 C# 特定方法。

© www.soinside.com 2019 - 2024. All rights reserved.