【发布时间】:2018-04-17 05:33:52
【问题描述】:
我有一个用于生产线的数据库。它有一个 Orders 表、一个 Ordertracker 表、一个 Item 表和一个 Itemtracker 表。
订单和项目都与状态具有多对多关系。跟踪器表以这样一种方式解决这些关系,即一个项目可以在跟踪器中有多个条目 - 每个条目都有特定的状态。
我试图上传一张表格的图片以使事情更清楚,但可惜我的积分还不够:C
我需要查找 Itemtracker 表中最后状态满足条件的项目,“3”或“0”。
然后我需要得到这些项目中的第一个。
我用来完成此操作的步骤如下:
- 获取所有具有一定状态的订单。
- 获取该订单中的所有项目。
- 获取最后状态为 = 0 或 3 的所有项目。
- 获取这些项目中的第一个。
我的代码如下:
public ITEM GetFirstItemFailedOrNotInProductionFromCurrentOrder()
{
var firstOrder = GetFirstOrderInProductionAndNotCompleted();
var items = ERPContext.ITEM.Where(i => i.OrderID == firstOrder.OrderID) as IQueryable<ITEM>;
if (CheckStatusOfItems(items) != null)
{
var nextItem = CheckStatusOfItems(items);
return nextItem ;
}
else
{
return null;
}
}
private ITEM CheckStatusOfItems(IQueryable<ITEM> items)
{
List<ITEM> listOfItemsToProduce = new List<ITEM>();
foreach (ITEM item in items.ToList())
{
var lastStatusOfItem = ERPContext.ITEMTRACKER.Where(it => it.ItemID == item.ItemID)
.OrderByDescending(it => it.ItemTrackerID).FirstOrDefault();
if (lastStatusOfItem.ItemStatus == (int)ItemStatus.Failed || lastStatusOfItem.ItemStatus == (int)ItemStatus.Confirmed)
{
listOfItemsToProduce.Add(item);
}
}
return listOfItemsToProduce.FirstOrDefault();
}
现在,这一切正常并返回了我需要的东西,但我知道这可能不是最好的方法。因为现在我的 IQueryable 项目集合永远不会包含超过 6 个项目 - 但如果它可以变得更大,那么在 IQueryable 上调用 ToList() 并迭代内存中的结果可能不是一个好主意。
有没有更好的方法来遍历 IQueryable 项目以获取具有特定状态作为其最新状态的项目,而无需调用 ToList() 并遍历结果?
任何建议将不胜感激。
【问题讨论】:
-
如果你懒加载信息,遍历 IQueryable 会非常慢。然后每个循环成为一个新的查询。
ITEMTRACKER是否与您的模型中的ITEM没有关联? -
顺便说一句,您应该将
CheckStatusOfItems的结果缓存到一个变量中,然后检查该变量是否为空。否则,您将调用它两次并执行两次查询。也就是说,您可以将整个第一个方法折叠到var firstOrder=... ; var items=... ; return CheckStatusOfItems(items);,因为如果它不为 null,则返回结果,如果为 null,则返回 null,因此与返回 (null) 结果相同 -
是的,我想是的,ITEMTRACKER 是将ITEM 表连接到ITEMSTATUS 表的表。 ItemID 和 OrderID 是 ITEM 中的 PK。 ItemID、OrderID 和 ItemStatus 是 ITEMTRACKER 中的 FK - PK 是 ItemTrackerID。任何建议如何解决这个问题?谢谢
-
另外,更一般地说:如果您只想返回集合中的第一个匹配项,请不要遍历整个列表并将所有匹配项添加到另一个列表中,然后最后返回第一项那个集合...只需返回满足您条件的第一个项目遇到它时,然后在循环后返回
return null -
注意!谢谢pinkfloydx33
标签: c# database linq foreach iqueryable