简体   繁体   English

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

[英]LINQ Query across complex parent/child/parent/child relationships

This is probably a snap for a LINQ pro, but this is beyond my basic capacity. 对于LINQ pro来说,这可能是个小问题,但这超出了我的基本能力。 We have six tables accessed through Entity Framework: 我们通过实体框架访问了六个表:

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

The Stores, ShoppingDays, and Transactions tables are straightforward and don't need commenting. “商店”,“ ShoppingDays”和“交易”表很简单,不需要注释。 However, each transaction purchases a single color of paint. 但是,每笔交易都购买一种颜色的油漆。 Each color of paint consists of a mix of color dye percentages that add up to 100%. 每种颜色的油漆均由多种百分比的染料组成,这些百分比总计达100%。

I'd like to sum up all of the dollars spent on each dye on each day at each store. 我想总结一下每一家商店每天在每种染料上花费的所有美元。 Imagine store1 has two transactions on day 1. One transaction for $30 for a purchase of Purple Paint (40% Red, 40% Blue, 20% Black) and another for $20 of Pink Paint (20% Red, 80% White). 想象一下store1在第1天有两笔交易。一笔交易以30美元的价格购买了紫色涂料(40%红色,40%蓝色,20%黑色),另一笔交易的价格为20美元的粉红色涂料(20%红色,80%白色)。 The results would look like 结果看起来像

Store1,1,Red,$16 Store1,1,红色,$ 16
Store1,1,Blue,$12 Store1,1,Blue,$ 12
Store1,1,Black,$6 Store1,1,黑色,$ 6
Store1,1,White,$16 Store1,1,White,16美元

Any help would be most appreciated. 非常感激任何的帮助。 I'm not really even sure where to start. 我什至不知道从哪里开始。 I did an inner join of all the tables and then put the data into an excel pivot table to extract the data. 我对所有表进行了内部联接,然后将数据放入excel数据透视表中以提取数据。 Obviously that's not correct. 显然,这是不正确的。

I started with the following. 我从以下内容开始。 It provides a table that shows each dye purchase for each transaction. 它提供了一个表,该表显示了每笔交易的每种染料购买量。 I'd like to sum up those purchases for each store and shopping day, but I'm not sure how. 我想总结每个商店和购物日的购买情况,但是我不确定如何进行。

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
                           });

Here is the equivalent of the classical SQL way. 这等效于经典SQL方式。

First a subquery that groups by {ShoppingDayId, DyeId} and calculates Sum(Percent * Amount) : 首先是一个子查询,该子查询按{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) };

Then join to other tables to get the additional information needed: 然后连接到其他表以获取所需的其他信息:

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
    };

The subquery could be embedded in the actual query, I've used a separate variable just for readability (it has no effect on the EF generated SQL query). 子查询可以嵌入到实际查询中,为了方便阅读,我使用了一个单独的变量(它对EF生成的SQL查询没有影响)。 Also you may need to update the field names / casing to match the actual models, but this should give you the idea. 另外,您可能需要更新字段名称/大小写以匹配实际模型,但这应该可以为您提供帮助。

I modified Ivan's answer into a single query. 我将Ivan的答案修改为一个查询。 It's very slow, but it works! 这很慢,但是可以用!

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) };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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