【问题标题】:How to sum the values of a specific column attribute of individual rows returned using a LINQ expression? (C#)如何对使用 LINQ 表达式返回的各个行的特定列属性的值求和? (C#)
【发布时间】:2020-10-18 18:27:17
【问题描述】:

我想使用基于某个传递值的 LINQ 表达式来挑选出表中的行,然后对这些行中的每一行的特定列属性求和,同时保持各行的总和彼此分开。

用户使用数量输入输入特定数量值 - 此传递的数量值需要在 LINQ 表达式中使用,以过滤出满足所需条件的行。

下面是分配给传递的数量值的变量:

int quantitySelected;
JObject passedQuantity = JObject.Parse(data);
quantitySelected = (int)passedQuantity["qtySelect"]

“quantitySelected”现在等于用户传递的值 - 现在,在 LINQ 表达式中使用此值,我希望能够根据满足的条件过滤特定表(InvoiceLine),然后根据外键标识符 (ProductID) 包含所有过滤后的行:

var dynamicReader = DBAccessor.InvoiceLines.Where(zz => zz.Quantity >= quantitySelected).Include(yy => yy.ProductID);

数据库结构的相关摘录如下:

我希望将数量大于或等于用户输入的所有行存储在动态阅读器中,并参考与它们关联的 ProductID。比如:

我希望能够挑出 ProductID 为 8 的行(可以在此处看到两次),然后将它们的数量相加,(因此 ProductID 8 最终的总和为 6)等等(对于每个重复的 ProductID)。

有没有办法使用 LINQ 查询表达式来完成此任务?还是我需要使用额外的 C#?

【问题讨论】:

  • 你试过DBAccessor.InvoiceLines.Where(zz => zz.ProductID == 8).Sum(x => x.Quantity)吗?
  • 我真的不明白这是如何解决问题的,因为 OP 希望使用数量值来过滤数据@SowmyadharGourishetty
  • "ProductID 为 8 的行" - 行,确定吗?你期望结果是什么类型? .GroupBy(r => r.ProductID).Select(rg => new { ProductID = rg.Key, Quantity = rg.Sum(r => r.Quantity) })

标签: c# asp.net linq lambda


【解决方案1】:

我希望能够挑出 ProductID 为 8 的行(此处可以看到两次),然后将它们的数量相加

这很好。显然你想要完整的行,在你想要 ProductId 和数量总和的行中。但是您想对其他属性做什么:您想要 InvoiceLineId 7 还是 10?发票 ID 3 还是 4?还是您只对总和感兴趣?

我的建议是创建具有相同 ProductId 的 InvoiceLine 组。为此,您可以使用 GroupBy。使用参数 resultSelector 在最终结果中选择您想要的属性:

var result = DBAccessor.InvoiceLines
    .Where(invoiceLine => invoiceLine.Quantity >= quantitySelected)

    // group the remaining invoicelines into groups with the same productId
    .GroupBy(invoiceLine => invoiceLine.ProductId,

    // parameter result selector: use the common productId and all invoiceLines
    // that have this productId to make one new:
    (productId, invoiceLinesWithThisProductId) => new
    {
        ProductId = productId,
        Quantity = invoiceLinesWithThisProductId
                   .Select(invoiceLine => invoiceLine.Quantity)
                   .Sum(),

        ... // other properties, you didn't specify what you want
    });

【讨论】:

    【解决方案2】:

    阅读说明后,您似乎愿意将列表中的重复行合并为一个并总结重复行的数量。您可以使用GroupBy 语句来获得所需的结果。

    这是一个示例,您可以根据需要进一步修复它。

    var dynamiceReader = DBAccessor.InvoiceLines.Where(x=> x.Quantity >= quantitySelected).GroupBy(e => e.ProductID).Select(product =>
    {
        var p = product.First();
        return new
        {
            InvoiceLineID = p.InvoiceLineID,
            InvoiceID = p.InvoiceID,
            ProductID = p.ProductID,
            Quantity = product.Sum(sum => sum.Quantity)
        };
    });
    

    同样,如果你也想包含合并后的 Id,那么你可以像下面这样修改它:

    InvoiceLineID = string.Join(", ", product.Select(x => x.InvoiceLineID)),
    

    【讨论】:

    • 我不完全确定您在这里所做的事情背后的逻辑?在我的程序中实现这一点会引发错误,“无法将带有语句体的 lambda 表达式转换为表达式树”
    • 这在技术上意味着您只能在 IEnumerable 集合的 Lamba 表达式中使用语句体。只需将结果转换为 IEnumerable。将.GroupBy(e => e.ProductID) 替换为.GroupBy(e => e.ProductID).AsEnumerable()
    猜你喜欢
    • 2012-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多