当其他字段相同时,获取两个字段的总和 - Linq

时间:2017-06-03 13:32:47

标签: c# linq

这是我的疑问:

var query = from buy in db.tblCustomerBuys.AsEnumerable()
            select new
            {
                Year = Convert.ToInt32(buy.BuyDate.Substring(0, 4)),
                ProductID = Convert.ToInt32(buy.ProductID),
                Price = Convert.ToDecimal(buy.TotalPrice),
                Amount = Convert.ToDouble(buy.Amount),
                Major = (Convert.ToBoolean(db.tblCustomers.First(x => x.CustomerID == buy.CustomerID).IsMajor) == true ? "Major" : "Normal"),
                Month = ClassDate.MonthName(Convert.ToInt32(buy.BuyDate.Split('/')[1])),
                Season = ClassDate.SeasonName(Convert.ToInt32(buy.BuyDate.Split('/')[1]))
            };

表格是关于客户的'购买。我需要得到每个产品ID的价格和金额的总和,其中所有其他字段都是相同的。目前输出是针对表中的每一行。

例如我们有产品1:

Year: 2012, ID: 1, Price: 12000, Amount: 2k, Major: Normal, Month: 2, Season: 1
Year: 2012, ID: 1, Price: 10000, Amount: 3k, Major: Normal, Month: 2, Season: 1

你可以看到除了Price和Amount之外的所有其他字段是相同的,在这种情况下我需要得到价格和金额的总和:

Year: 2012, ID: 1, Price: 22000, Amount: 5k, Major: Normal, Month: 2, Season: 1

所以输出记录会更少。我该如何快速完成这项工作?

2 个答案:

答案 0 :(得分:3)

1 - 您不需要使用AsEnumerable(),这将导致将所有数据提取到内存中,这可能不是必需的。如果只能获取分组结果,那可能会快得多,请参阅下一点。

2 - 你需要分组

db.tblCustomerBuys.
        .GroupBy(buy => new 
        {
            Year = Convert.ToInt32(buy.BuyDate.Substring(0, 4)),
            ProductID = Convert.ToInt32(buy.ProductID),
            Major = (Convert.ToBoolean(db.tblCustomers.First(x => x.CustomerID == buy.CustomerID).IsMajor) == true ? "Major" : "Normal"),
            Month = ClassDate.MonthName(Convert.ToInt32(buy.BuyDate.Split('/')[1])),
            Season = ClassDate.SeasonName(Convert.ToInt32(buy.BuyDate.Split('/')[1]))
        })
        .Select(x => new
        {
            Year = x.Key.Year,
            ProductID = x.Key.ProductId,
            Price = x.Sum(i => Convert.ToInt32(i.Price)),
            Amount = x.Sum(i => Convert.ToDouble(i.Amount)),
            Major = x.Key.Major,
            Month = x.Key.Month,
            Season = x.Key.Season
        }).ToList();

请记住,如果你在EF核心中运行它(截至编写本答案时),所有数据将被提取到内存然后分组,这比在DBMS中完成的要慢得多。这对您来说可能不是问题,也不是EF6.x中的问题

答案 1 :(得分:1)

试试这个。您需要使用GroupBy来获取具有相同年份和ID的所有产品。哟可能还需要对Major,Month和Season进行分组。

var totals = query.GroupBy(x => new { year = x.Year, id = x.ProductID }).Select(x => new {
                Year = x.Key.year,
                ProductID = x.Key.id,
                Price = x.Sum(y => y.Price),
                Amount = x.Sum(y => y.Amount),
                Major = x.First().Amount,
                Month = x.First().Month,
                Season = x.First().Season
            }).ToList();