我有一个用于生产线的数据库。它有一个Orders表,Ordertracker表,Item表和Itemtracker表。
订单和商品都与状态有多对多的关系。跟踪器表以一种方式解决这些关系,即项目在跟踪器中可以有多个条目 - 每个条目都具有特定状态。
我试图上传一张桌子的图片以使事情更清晰但是唉,我还没有足够的分数:C
我需要查找Itemtracker表中最后一个状态符合条件的项目,' 3'或者' 0'。
然后我需要获得这些项目中的第一项。
我用来完成此任务的步骤如下:
我的代码如下:
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()并预先通过结果?
非常感谢任何建议。
答案 0 :(得分:4)
使用LINQ查询语法,您可以声明性地构建单个查询,这与编写命令式迭代的方式非常相似。 foreach
转换为from
,var
转换为let
,if
转换为where
:
private ITEM CheckStatusOfItems(IQueryable<ITEM> items)
{
var query =
from item in items
let lastStatusOfItem = ERPContext.ITEMTRACKER
.Where(it => it.ItemID == item.ItemID)
.OrderByDescending(it => it.ItemTrackerID)
.FirstOrDefault()
where (lastStatusOfItem.ItemStatus == (int)ItemStatus.Failed || lastStatusOfItem.ItemStatus == (int)ItemStatus.Confirmed)
select item;
return query.FirstOrDefault();
}
或者使用from
代替let
和Take(1)
代替FirstOrDefault()
:
private ITEM CheckStatusOfItems(IQueryable<ITEM> items)
{
var query =
from item in items
from lastStatusOfItem in ERPContext.ITEMTRACKER
.Where(it => it.ItemID == item.ItemID)
.OrderByDescending(it => it.ItemTrackerID)
.Take(1)
where (lastStatusOfItem.ItemStatus == (int)ItemStatus.Failed || lastStatusOfItem.ItemStatus == (int)ItemStatus.Confirmed)
select item;
return query.FirstOrDefault();
}