数据库包含订单。 订单可以包含在一组订单中。 对于每组订单,它可以包含 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 哪里不正确吗?
这是失败的部分 -
grp.Select(g => g.OrderId).ToList()
- select 子句中不能有 .ToList() 。删除它,你应该没问题。
问题在于 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
。
您的问题是您在 select 语句中选择了一个列表。
select new OrdersGroup
{
GroupOrderId = grp.Key,
OrderIds = grp.Select(g => g.OrderId).ToList()
/////////////////////////////////////^^^^^^^^^HERE
}
您需要做的就是将
OrderIds
更改为 IEnumerable<int>
,然后去掉 ToList
。
这是因为您尝试在查询的一部分中调用
ToList()
,该查询将成为原始 SQL 并在源(即 SQL Server,而不是 CLR)执行。我不知道你的数据到底是什么,所以我不一定能就如何修复它提出准确的建议,但我会尝试在此查询后进行 ToList()
调用,或者只是不进行全部操作。 IEnumerable
可能会提供您需要的任何功能,如果您删除 Select
调用,ToList()
将返回该功能。
顺便说一句,因为我没有明确表示,我指的是 select 中的
ToList()
调用 -(倒数第二行)OrderIds = grp.Select(g => g.OrderId).ToList()
另一个很好。它是在 SQL 查询的结果上执行的,这完全没问题,只是您无法在将由 SQL 提供程序执行的查询中调用 C# 特定方法。