LINQ查询复杂的父/子/父/子关系

时间:2017-01-31 03:49:30

标签: c# entity-framework linq

对于LINQ专业人员而言,这可能是一个快照,但这超出了我的基本能力。我们通过实体框架访问了六个表:

Stores { Storeid, Description }
ShoppingDays { ShoppingDayid, Date, Storeid }
Transactions { Transactionid, Amount, ShoppingDayid, PaintColorid }
PaintColors { PaintColorid }
DyeAllocations { DyeAllocationid, PaintColorid, Percent, DyeId }
Dyes { DyeId, Name }

Stores,ShoppingDays和Transactions表格简单明了,不需要评论。但是,每笔交易都会购买一种颜色的油漆。每种颜色的涂料都由混合颜色染料百分比组成,加起来达到100%。

我想在每家商店的每一天总结每种染料上花费的所有金额。想象一下,store1在第1天有两笔交易。一笔交易为30美元购买紫色油漆(40%红色,40%蓝色,20%黑色),另一笔交易为20美元粉红漆(20%红色,80%白色)。结果看起来像

Store1,1,红色,$ 16
Store1,1,蓝,$ 12个
Store1,1,黑色,$ 6
Store1,1,白色,$ 16

任何帮助都将非常感激。我甚至不确定从哪里开始。我对所有表进行了内连接,然后将数据放入excel数据透视表中以提取数据。显然这不正确。

我从以下开始。它提供了一个表格,显示每笔交易的每次染料购买。我想总结每个商店和购物日的购买情况,但我不确定如何。

var dyeValues = (from store in db.stores
                           join sd in db.shoppingdays on store.storeId equals sd.storeId
                           join tr in db.transactions on sd.shoppingdayId equals tr.shoppingdayId
                           join pc in db.paintcolors on tr.paintcolorId equals pc.paintcolorId
                           join da in db.dyeallocations on pc.paintcolorId equals da.paintcolorId
                           where da.percent > 0.0m
                           select new
                           {
                               store.Description,
                               shoppingdayDate = sd.Date,
                               da.dye.Name,
                               da.percent,
                               Allocation = da.percent * tr.Amount
                           });

2 个答案:

答案 0 :(得分:2)

这是经典SQL方法的等价物。

首先按{ShoppingDayId, DyeId}分组并计算Sum(Percent * Amount)

的子查询
var dyeAllocations =
    from tr in db.Transactions
    join pc in db.PaintColors on tr.PaintColorId equals pc.PaintColorId
    join da in db.DyeAllocations on pc.PaintColorId equals da.PaintColorId
    where da.Percent > 0.0m
    group new { Allocation =  da.Percent * tr.Amount }
    by new { tr.ShoppingDayId, da.DyeId } into g
    select new { g.Key.ShoppingDayId, g.Key.DyeId, Allocation = g.Sum(e => e.Allocation) };

然后加入其他表格以获取所需的其他信息:

var dyeValues =
    from da in dyeAllocations
    join dye in db.Dyes on da.DyeId equals dye.DyeId
    join sd in db.ShoppingDays on da.ShoppingDayId equals sd.ShoppingDayId
    join store in db.Stores on sd.StoreId equals store.StoreId
    select new
    {
        store.Description,
        sd.Date,
        dye.Name,
        da.Allocation
    };

子查询可以嵌入到实际查询中,为了便于阅读,我使用了一个单独的变量(它对EF生成的SQL查询没有影响)。此外,您可能需要更新字段名称/大小写以匹配实际模型,但这应该可以为您提供想法。

答案 1 :(得分:0)

我将Ivan的答案修改为单个查询。它很慢,但它确实有效!

var deyValues = from cs in account.stores
       join sd in db.shoppingdays on cs.storeId equals sd.storeId
       join tr in db.transactions on sd.shoppingdayId equals tr.shoppingdayId
       join pc in db.paintcolors on tr.paintcolorId equals pc.paintcolorId
       join da in db.dyeallocations on pc.paintcolorId equals da.paintcolorId
       where da.AfterTaxOptimalPortion > 0.0m
       group new { Allocation = da.Percent * tr.Amount }
       by new { AccountName = cs.Account.Name, ShoppingDate = sd.Date, DyeName = da.dye.Name } into g
       select new { g.Key.AccountName, g.Key.ShoppingDate, g.Key.DyeName, Total = g.Sum(el => el.Allocation) };