[英]Iterate over an IQueryable without calling ToList()
I have a DB used for a production line. 我有一个用于生产线的数据库。 It has an Orders table, and Ordertracker table, an Item table, and an Itemtracker table.
它具有一个Orders表,一个Ordertracker表,一个Item表和一个Itemtracker表。
Both Orders and Items have many-to-many relationships with status. 订单和项目都与状态具有多对多关系。 The tracker tables resolves these relationships in such a way that an item can have multiple entries in the tracker - each with a particular status.
跟踪器表通过以下方式解析这些关系:项目可以在跟踪器中具有多个条目-每个条目都具有特定的状态。
I tried to upload a picture of the tables to make things clearer but alas, I don't have enough points yet :C 我试图上传一张桌子的图片以使情况更清楚,但是,我还没有足够的要点:C
I need to find items whose last status in the Itemtracker table meets a condition, either '3' or '0'. 我需要找到在Itemtracker表中最后一个状态满足“ 3”或“ 0”条件的项目。
I then need to get the first one of these items. 然后,我需要获得这些物品中的第一个。
The steps I am using to accomplish this are as follows: 我用来完成此操作的步骤如下:
My code is as follows: 我的代码如下:
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();
}
Now, this all works fine and returns what I need but I'm aware that this might not be the best approach. 现在,这一切都可以正常工作并返回我需要的东西,但是我知道这可能不是最好的方法。 As it is now my IQueryable collection of items will never contain more than 6 items - but if it could grow larger, then calling ToList() on the IQueryable and iterating over the results in-memory would probably not be a good idea.
到现在为止,我的IQueryable项目集合将永远不会包含超过6个项目-但是,如果它可能变得更大,则在IQueryable上调用ToList()并在内存中迭代结果可能不是一个好主意。
Is there a better way to iterate through the IQueryable items to fetch out the items that have a certain status as their latest status without calling ToList() and foreaching through the results? 有没有更好的方法可以遍历IQueryable项以获取具有特定状态的项作为最新状态,而无需调用ToList()并遍历结果呢?
Any advice would be much appreciated. 任何建议将不胜感激。
Using LINQ query syntax, you can build declaratively a single query pretty much the same way you wrote the imperative iteration. 使用LINQ查询语法,您可以声明性地构建单个查询,几乎与编写命令式迭代的方式相同。
foreach
translates to from
, var
to let
and if
to where
: 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();
}
or alternatively using from
instead of let
and Take(1)
instead of 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();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.