Как совместить LEFT JOIN, GROUP BY и SUM в LINQ? - PullRequest
0 голосов
/ 24 декабря 2018

Я хочу написать свой SQL-запрос, используя LINQ в C #.

Вот мой запрос (для каждой Организации отображают свой Id, Name, Director, Analyst и общую сумму дохода из таблицы «Доход»):

SELECT
    o.Id,
    o.Name,
    d.FirstName + ' ' + d.LastName AS Director,
    a.FirstName + ' ' + a.LastName AS Analyst,
    SUM(i.Amount) AS TotalIncome
FROM Organization o
    LEFT JOIN Employee d ON o.DirectorId = d.Id
    LEFT JOIN Employee a ON o.AnalystId = a.Id
    LEFT JOIN Income i ON o.Id = i.OrganizationId
GROUP BY
    o.Id, 
    o.Name, 
    d.FirstName,
    d.LastName,
    a.FirstName,
    a.LastName

Я уже пробовал что-то вроде этого:

from o in Organization
join director in Employee on o.DirectorId equals director.Id into directorJoin
from d in directorJoin.DefaultIfEmpty()
join analyst in Employee on o.AnalystId equals analyst.Id into analystJoin
from a in analystJoin.DefaultIfEmpty()
join income in Income on o.Id equals income.OrganizationId into incomeJoin
group o by new 
{
    o.Id,
    o.Name,
    Director = d.FirstName + ' ' + d.LastName,
    Analyst = a.FirstName + ' ' + a.LastName,
    TotalIncome = (decimal?)incomeJoin.Sum(x => x.Amount)
} into g
  select g.Key

, но моя программа выдает мне исключение:

Вложенный запрос не поддерживается,Operation1 = 'GroupBy' Operation2 = 'MultiStreamNest'

Буду очень признателен за любую помощь.

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Я использовал Свойства навигации , предложенные Герт Арнольд .Вот упрощенная версия моей проблемы и ее решение:

Модели:

public class Employee
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class Income
{
    public int Id { get; set; }
    public int OrganizationId { get; set; }
    public decimal Amount { get; set; }
}

public class Organization
{
    public int Id { get; set; }
    public string Name { get; set; }

    public int AnalystId { get; set; }
    public virtual Employee Analyst { get; set; }

    public int DirectorId { get; set; }
    public virtual Employee Director { get; set; }

    public virtual ICollection<Income> Incomes { get; set; }
}

Запрос:

class Program
{
    static void Main(string[] args)
    {
        var context = new Context();

        var queryResult = context.Organizations.Select(x => new
        {
            x.Id,
            x.Name,
            Director = x.Director.FirstName + " " + x.Director.LastName,
            Analyst = x.Analyst.FirstName + " " + x.Analyst.LastName,
            TotalIncome = x.Incomes.Sum(y => y.Amount)
        });

    }
}
0 голосов
/ 03 января 2019

Вы не хотите выполнять суммирование в ключе группы - сделайте это за пределами группы:

from o in Organization
join director in Employee on o.DirectorId equals director.Id into directorJoin
from d in directorJoin.DefaultIfEmpty()
join analyst in Employee on o.AnalystId equals analyst.Id into analystJoin
from a in analystJoin.DefaultIfEmpty()
join income in Income on o.Id equals income.OrganizationId into incomeJoin
group o by new 
{
    o.Id,
    o.Name,
    Director = d.FirstName + ' ' + d.LastName,
    Analyst = a.FirstName + ' ' + a.LastName,
    i.Amount
} into g
  select new 
{
    g.Key.Id,
    g.Key.Name,
    g.Key.Director,
    g.Key.Analyst,
    TotalIncome = (decimal?)g.Sum(i => i.Amount)
}

Вы также можете проверить нулевые значения, поскольку вы 'повторно осталось присоединиться к d, i и a

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...