简体   繁体   中英

Join and Group Two Tables and Get Sum of Fields - Linq C#

There is tow tables for my products, which one is related to main warehouse and the other one is related to a little store. Both tables keep amounts of products.

tblWareHouse
-----------------------------------
ProductID   ProductSeries    Amount
   1           600             80
   1           601             50
   2           300             90

tblStore
-----------------------------------
ProductID   ProductSeries    Amount
   1           700             20
   1           601             40
   2           400             10

Every product has a unique ProductSeries number. I need to join and group these two tables and get sum of amount Products by ProductID for two warehouse and store like this:

Output
------------------------------------------
ProductID   StoreAmount    WareHouseAmount
    1          60               130
    2          10                90

My Code is this:

var q = from d in db.tblWareHouses
         join s in db.tblStores on d.ProductID equals s.ProductID
         group new { d, s } by d.ProductID into v
         select new
         {
             ID = Convert.ToInt32(v.Key),
             WareHouseAmount = v.Sum(x => x.d.Amount),
             StoreAmount = v.Sum(x => x.s.Amount),
         };

But there is a problem, it will generate extra output rows and while summing the amount it will give me more than it is. for example for ProductID 1 in warehouse it will generate 3 rows of store in joining and while summing it will sum all of the extra rows. I need to remove the duplicate ones. Hope I'm clear enough. How to fix it?

Because of the sum in each table, I was able to achieve by splitting sum into separate queries:

var q1 = tblWareHouses.AsEnumerable()
    .GroupBy(r => r.ProductID)
    .Select(a => new
    {
        ProductID = a.Key,
        Amount = a.Sum(r => r.Amount)
    }).ToList();


var q2 = tblStores.AsEnumerable()
    .GroupBy(r => r.ProductID)
    .Select(a => new
    {
        ProductID = a.Key,
        Amount = a.Sum(r => r.Amount)
    }).ToList();

var q3 = (from d in q1
    join s in q2 on d.ProductID equals s.ProductID
    group new {d, s} by d.ProductID
    into v
    select new
    {
        ID = v.Key,
        WareHouseAmount = v.Sum(x => x.d.Amount),
        StoreAmount = v.Sum(x => x.s.Amount),
    }).ToList();

OUTPUT:

在此处输入图片说明

Join will most likely work like cartesian join between rows with the same ProductID, so it produces wrong results. I'd try to abandon join and grouping and use Zip() instead. It takes corresponding rows from both collections joins then together with new result. It's far from ideal solution, since it most likely will evaluate inside computer's memory. I think you can avoid this with sql, but each table needs to be projected to a collection containing row number first (ie. using RANK function), then join needs to be on this row number.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM