【发布时间】:2019-11-04 12:44:04
【问题描述】:
我正在尝试查找ReturnItems 的列表,其中退回的单个商品的数量超过了该商品的原始订购数量。所以这里有 2 个不同的对象列表 - IEnumerable<ReturnItem> 和 IEnumerable<OrderItem>。问题在于,根据退货的来源(我们的工作流程中有多个可以退货的地方),给定ReturnItem 上的ItemNumber 可能为空。在这种情况下,我们需要依靠ReturnItem.OrderItemId 来匹配OrderItem。
我已经使用 LINQ 解决了这个问题,但它需要一个嵌套的 for 循环(在引擎盖下),所以我尽量避免这种情况,同时还要保持可读性。换句话说,我想避免运行时间O(N^2) 并寻找 O(N) 或更好,但同时保持可读性(我知道我在这里要求很多,但我想我会看看是否有人有创造性的解决方案)。我创建了一个解决方案,其中我有两个用于订单项的字典。其中一个,key是item number,另一个key是order Item Id。这有效并解决了性能问题,但我完全失去了可读性。
这是我原来的 LINQ 语句:
// ItemsForReturn = IEnumerable<ReturnItem>
// OrderItems = IEnumerable<OrderItem>
var invalidQuantityItems = message.ItemsForReturn.Where(returnItem =>
{
var matchingOrderItemQuantity = message.OrderItems
.Where(orderItem => orderItem.ItemNumber.Equals(returnItem.ItemNumber) || orderItem.OrderItemId == returnItem.OrderItemId)
.Sum(orderItem => orderItem.Quantity);
return matchingOrderItemQuantity < returnItem.Quantity;
});
以及上面用到的变量的对应类型:
public class ReturnItem
{
public int OrderItemId {get; set;}
public string ItemNumber {get; set;}
public int Quantity {get; set;}
// There's more properties but these are the ones that matter
{
public class OrderItem
{
public int OrderItemId {get; set;}
public string ItemNumber {get; set;}
public int Quantity {get; set;}
// There's more properties but these are the ones that matter
{
我预计var invalidQuantityItems 将是一个IEnumerable<ReturnItems>,其单个商品的数量大于订购的数量(即,他们试图返回的数量超过他们最初订购的数量)。
干杯!
【问题讨论】:
-
一般来说,您可以通过将最有可能结束评估的条件放在首位来优化多个条件。
-
同意@RufusL 你希望你最有可能首先是错误的条件,但至于优化,我不会太担心,SQL 查询规划器将处理大部分的你,前提是你的索引设置正确。
-
为什么不总是使用
int OrderItemId字段进行比较? -
因为根据返回创建的来源,它可能不存在。 IE。有时商品编号和订单商品 ID 都存在,有时是其中之一。
-
OrderItem是如何使用的?OrderItemId和ItemNumber有区别吗?
标签: c# .net algorithm performance