Вопрос или проблема
SELECT
c.*,
SUM(h.Harvested) AS Harvested
FROM
Plantings c
LEFT JOIN
Harvests h ON c.Id = h.Id
Этот код используется для выбора всех столбцов из таблицы Plantings
и одного столбца (т.е. общей суммы собранного) из таблицы Harvests
.
Моя задача — переписать этот код с использованием метода LINQ.
Таблица Plantings
Id | Item | Planted |
---|---|---|
3 | Морковь | 2.00 |
4 | Яблоко | 1.00 |
Таблица Harvests
HId | Item | Harvested | Id |
---|---|---|---|
1 | Морковь | 10.00 | 3 |
2 | Яблоко | 20.00 | 4 |
3 | Морковь | 5.00 | 3 |
Вот что я пробовал
IEnumerable DataSource = (from c in _context.Plantings
join h in _context.Harvests on c.Id equals h.Id
select t1).ToList();
Ожидаемая таблица результата
Id | Item | Harvested |
---|---|---|
3 | Морковь | 15.00 |
4 | Яблоко | 20.00 |
Вы можете просто создать объект с подзапросом в вашем LINQ.
var data = (
from p in _context.Plantings
select new {
p,
Harvested = _context.Harvests.Where(h => h.Id == p.Id).Sum(h => h.Harvested),
}
).ToList();
Обычно у вас будет какая-то связь по внешнему ключу, тогда вы можете просто сделать
var data = (
from p in _context.Plantings
select new {
p,
Harvested = p.Harvests.Sum(h => h.Harvested),
}
).ToList();
Следующее поможет вам достичь желаемого результата:
var finalResult = (from h in harvests
join p in plantings on h.Id equals p.Id
group h by new { p.Id, p.Item } into g
select new
{
Id = g.Key.Id,
Item = g.Key.Item,
Harvested = g.ToList().Sum(m => m.Harvested)
}).ToList();
что эквивалентно
var finalResult = harvests.Join(plantings, h => h.Id, p => p.Id, (h, p) => (h,p))
.GroupBy(g => new { g.h.Id, g.h.Item }).Select(f => new
{
Id = f.Key.Id, Item = f.Key.Item, Harvested = f.Sum(d => d.h.Harvested)
});
Ответ или решение
Для получения всех столбцов из одной таблицы и агрегированного значения из другой с использованием LINQ можно воспользоваться оператором join
, с последующей группировкой и агрегацией данных. Рассмотрим таблицы, представленные в вопросе.
Вам необходимо извлечь все данные из таблицы Plantings
и общее количество собранного урожая (Harvested
) из таблицы Harvests
, где соединение происходит по полю Id
. Используя LINQ, можно достичь этого следующими способами.
Способ 1: Использование запроса LINQ (Query Syntax)
var result = (
from p in _context.Plantings
join h in _context.Harvests on p.Id equals h.Id into harvestGroup
select new
{
p.Id,
p.Item,
Harvested = harvestGroup.Sum(h => h.Harvested)
}
).ToList();
Способ 2: Использование метода расширения LINQ (Method Syntax)
var result = _context.Plantings.GroupJoin(
_context.Harvests,
p => p.Id,
h => h.Id,
(p, harvestGroup) => new
{
p.Id,
p.Item,
Harvested = harvestGroup.Sum(h => h.Harvested)
})
.ToList();
Объяснение кода
- Join: В обоих примерах данные из таблицы
Plantings
соединяются с данными из таблицыHarvests
на основе соответствияId
. - GroupJoin: Этот метод позволяет выполнить соединение и группировку данных одновременно.
- Агрегация: Используется метод
Sum()
для подсчета общего количестваHarvested
для каждой группы. - Анонимные типы: Для формирование результирующего списка используется создание анонимного типа, который включает поля
Id
,Item
и суммированное значениеHarvested
.
Результат
Ожидаемый результирующий набор данных будет содержать три столбца с агрегированным значением:
Id | Item | Harvested |
---|---|---|
3 | Carrot | 15.00 |
4 | Apple | 20.00 |
Таким образом, приведенные методы LINQ позволяют легко извлечь и отобразить данные из двух таблиц с использованием группировки и агрегации. Все указанные подходы подходят в зависимости от предпочтений, использованных стилей (query vs method syntax) и задач, которые вы хотите решить.