我试图找到一个ReturnItems列表,其中返回的单个项目的数量大于该项目的原始订购数量。所以这里有两个不同的对象列表-IEnumerable<ReturnItem>IEnumerable<OrderItem>。问题是,根据返回的来源(工作流中有多个地方可以进行返回),给定ItemNumber上的ReturnItem可能为空。在这种情况下,我们需要依赖于ReturnItem.OrderItemId来将其与OrderItem匹配。
我已经用LINQ解决了这个问题,但是它需要一个嵌套的for循环(在引擎盖下),所以如果可能的话,我会尽量避免这个问题,同时保持可读性。换句话说,我想避免O(n^2)的运行时间,寻找O(n)或更好的运行时间,同时保持可读性(我知道我在这里要求很多,但我想我会看看是否有人有创造性的解决方案)。我创建了一个解决方案,其中我有两个字典用于订购项目。其中一个键是项目编号,另一个键是订单项目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>的单个项目的数量大于订购的数量(即,他们试图返回比他们在第一时间订购的更多)。
干杯!

最佳答案

小的校正-当前实现的时间复杂度为O(n*m),并且你能得到的最好的是O(n+m)。
问题是如何有效地关联这两个集合在linq中,这是通过joins实现的,对于这种一对多类型的相关性-group join||标准的等价性将是两个组连接(匹配集)的结果的Union
谈到可读性、LINQ和连接,最好的方法是使用LINQ查询语法(有些人还称之为理解语法)。
因此,所讨论的查询可以有效地(并且希望是可读的)重写如下:

var invalidQuantityItems =
    from returnItem in message.ItemsForReturn
    join orderItem in message.OrderItems on returnItem.ItemNumber equals orderItem.ItemNumber
    into matchingOrderItems1
    join orderItem in message.OrderItems on returnItem.OrderItemId equals orderItem.OrderItemId
    into matchingOrderItems2
    let matchingOrderItemQuantity = matchingOrderItems1.Union(matchingOrderItems2)
        .Sum(orderItem => orderItem.Quantity)
    where matchingOrderItemQuantity < returnItem.Quantity
    select returnItem;

关于c# - 优化具有多个条件的嵌套where子句的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56707262/

10-09 23:33