使用LINQ时出现StackOverFlow未处理的错误”

时间:2018-08-15 14:30:11

标签: c# entity-framework linq

我有以下代码,它因“ StackOverFlow未处理的错误”而停止执行。

var Requests= GetList();// return List of Request objects

IQueryable<Order> pos= Enumerable.Empty<Order>().AsQueryable();
if (Requests != null)
 {
   if (Requests.Count > 0)
      {
       var GeneralReq = Requests.Select(loc => loc.Id).ToList();


pos = db.Order.Where(loc => loc.Deleted == false && GeneralReq.Any(a => a == loc.Id));
//HERE, stop executing with StackOverFlow Error.

      }
 }

问题恰在这里:

pos = db.Order.Where(loc => loc.Deleted == false && GeneralReq.Any(a => a == loc.Id));

1 个答案:

答案 0 :(得分:1)

不知道GetList()是做什么的,可能的问题是它返回的记录太多,无法安全地将ID注入您的.Any()表达式中。 EF希望将.Any()转换为查询,例如:

WHERE orders.OrderId IN(22,25,45,46,52,66,...)

这通常效率不高,并且您可以传递的ID数量受到限制。最好将这些条件解析为联接。我不确定这是否会导致堆栈溢出,所以我不相信您拥有的代码示例是否完整,因为如果没有.ToList()或类似的表达式,IQueryable<Order> pos表达式将尚未实现。

我将研究您可以在请求和订单之间解决的关系。如果请求实体作为对订单的引用,则可以更改GetList()以返回IQueryable<Request>然后获取订单:

IQueryable<Request> requests = GetList();
IQueryable<Order> orders = requests.Select(x => x.Order);

您可以从此处选择所需订单的详细信息,并具体化生成的数据。

IQueryable<Request> requests = GetList();
List<OrderViewModel> orderVMs = requests.Select(x => new OrderViewModel
{
  OrderId = x.Order.OrderId,
  RequestId = x.RequestId,
  CustomerName = x.Customer.Name,
  OrderNumber = x.Order.OrderNumber,
  // ...
}).ToList();

如果GetList()可以返回有效的#或结果,请使用.Take().Skip()而不是.ToList()来分页结果。