2017-01-31 4 views
0

Это, вероятно, привязка для LINQ pro, но это не соответствует моей основной емкости. У нас есть шесть таблиц, доступ через Entity Framework:LINQ Запрос через сложные отношения родительский/дочерний/родительский/дочерний

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

магазинах, ShoppingDays и Транзакции таблицы просты и не нужны комментирования. Однако каждая транзакция покупает один цвет краски. Каждый цвет краски состоит из сочетания цветовых красителей, которые составляют до 100%.

Я хотел бы суммировать все доллары, потраченные на каждый краситель в каждый день в каждом магазине. Представьте, что в магазине 1 есть две транзакции в первый день. Одна транзакция за 30 долларов США за покупку фиолетовой краски (40% красного, 40% голубого, 20% черного), а другая за 20 долларов от Pink Paint (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 
          }); 
+1

где «краска» ..? где это происходит? также, по крайней мере, поделитесь нами тем, что вы пробовали. –

+0

К сожалению, PaintId должен был быть PaintColorId. Честно говоря, я сделал плоское внутреннее соединение всех таблиц, а затем извлек данные, которые я хотел, используя сводную таблицу в Excel. Помимо этого, я начал с db.stores.selectmany (st => st.shoppingdays) .selectmany (sd => sd.transactions) ... и т. Д. Но я знаю, что это неправильный подход. Должен ли я начинать с красителей или красок и работать назад, может быть? – jlear

+1

Привет @jlear, Stackoveflow - это не место, где вы можете сказать, что у меня есть эти данные, я хочу, чтобы это было из этого. Вам нужно проявить некоторые усилия на вашей стороне. Проверьте: http://stackoverflow.com/help/how-to-ask – bit

ответ

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

подзапрос может быть вложена в самом запросе , Я использовал отдельную переменную только для удобства чтения (она не влияет на SQL-запрос, сгенерированный EF). Также вам может потребоваться обновить имена полей/корпуса, чтобы они соответствовали фактическим моделям, но это должно дать вам эту идею.

+0

Спасибо, Иван. Я попробую. – jlear

+0

Пригвожденный Иван! Я объединил ваши два запроса, взяв инструкцию группы и добавив ее в мое соединение. Это ужасно медленно, но теперь я знаю, как это сделать. Большое спасибо! – jlear

0

Я изменил ответ Ивана в один запрос. Это очень медленно, но это работает!

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) }; 
Смежные вопросы