Условный подсчет в группе Linq по нескольким столбцам с левым объединением - PullRequest
0 голосов
/ 11 февраля 2019

Я знаю, что есть тон подобных вопросов, и я прошел через многие из них, но все еще не могу понять, как это сделать в LINQ.Мне нужно создать запрос, извлекающий данные в виде этого чистого SQL-запроса:

SELECT p.ProcessId, p.Description, p.StartedOn, p.StartedBy, uuus.Name + ' ' + uuus.Surname AS StartedByName, p.FinishedOn, p.FinishedBy, uuu.Name + ' ' + uuu.Surname as FinishedByName, p.PlannedFinish, p.PlannedStart, COUNT(CASE WHEN h.IsCompleted IS NULL AND h.HandlingId IS NOT NULL THEN 1 END)
FROM JDE_Processes p LEFT JOIN JDE_Users uuu ON p.FinishedBy = uuu.UserId LEFT JOIN JDE_Handlings h ON h.ProcessId=p.ProcessId LEFT JOIN JDE_Users uuus ON uuus.UserId=p.StartedBy
GROUP BY p.ProcessId, p.Description, p.StartedOn, p.StartedBy,uuus.Name + ' ' + uuus.Surname, p.FinishedOn, p.FinishedBy, uuu.Name + ' ' + uuu.Surname, p.PlannedFinish, p.PlannedStart, p.Createdon
ORDER BY p.CreatedOn DESC

Вот моя версия linq, она в основном работает, но я не могу понять часть 'Count if h.IsCompleted = 0'..

var items = (from p in db.JDE_Processes
    join uuu in db.JDE_Users on p.FinishedBy equals uuu.UserId into finished
    from fin in finished.DefaultIfEmpty()
    join h in db.JDE_Handlings on p.ProcessId equals h.ProcessId into hans
    from ha in hans.DefaultIfEmpty()
    group new { p, fin }
    by new {
        p.ProcessId,
        p.Description,
        p.StartedOn,
        p.StartedBy,
        p.FinishedOn,
        p.FinishedBy,
        p.PlannedFinish,
        p.PlannedStart,
        fin.Name,
        fin.Surname
    } into grp
    orderby grp.Key.ProcessId descending
    select new Process
    {
        ProcessId = grp.Key.ProcessId,
        Description = grp.Key.Description,
        StartedOn = grp.Key.StartedOn,
        StartedBy = grp.Key.StartedBy,
        FinishedOn = grp.Key.FinishedOn,
        FinishedBy = grp.Key.FinishedBy,
        FinishedByName = grp.Key.Name + " " + grp.Key.Surname,
        PlannedStart = grp.Key.PlannedStart,
        PlannedFinish = grp.Key.PlannedFinish,
        HandlingStatus = grp.Count().ToString()
    });

Вопросы:

1) как заставить работать 'Count if h.IsCompleted = 0'?

2) Могу ли я использовать псевдонимы какого-либо рода?Я имею в виду, что в реальной версии этого запроса есть еще одно левое объединение join uuu in db.JDE_Users on p.StartedBy equals uuu.UserId into started from star in started.DefaultIfEmpty() Это приводит к тому, что у меня есть 2 столбца Имя и 2 Фамилия в grp.Как я могу назначить правильное поле для правильного поля вывода?Я имею в виду, как показано ниже:

select new Process
{
    ProcessId = grp.Key.ProcessId,
    Description = grp.Key.Description,
    StartedOn = grp.Key.StartedOn,
    StartedBy = grp.Key.StartedBy,
    StartedByName = grp.Key.Name + " " + grp.Key.Surname, // <-- how will it know which Name field to use? 
    FinishedOn = grp.Key.FinishedOn,
    FinishedBy = grp.Key.FinishedBy,
    FinishedByName = grp.Key.Name + " " + grp.Key.Surname,
    PlannedStart = grp.Key.PlannedStart,
    PlannedFinish = grp.Key.PlannedFinish,
    HandlingStatus = grp.Count().ToString()
}

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

Извините за ответ на мой вопрос, но я уже нашел ответ на 2).Я просто не знал, как создать псевдоним для свойства, когда у меня было 2 свойства с одинаковым именем (например, «Фамилия»).Ниже приведен код, содержащий псевдонимы, а также условный счетчик, решаемый NetMage:

var items = (from p in db.JDE_Processes
                             join uuu in db.JDE_Users on p.FinishedBy equals uuu.UserId into finished
                             from fin in finished.DefaultIfEmpty()
                             join uu in db.JDE_Users on p.StartedBy equals uu.UserId into started
                             from star in started.DefaultIfEmpty()
                             join h in db.JDE_Handlings on p.ProcessId equals h.ProcessId into hans
                             from ha in hans.DefaultIfEmpty()
                             where p.TenantId == tenants.FirstOrDefault().TenantId && p.CreatedOn >= dFrom && p.CreatedOn <= dTo
                             group new { p, fin, star, ha }
                             by new {
                                 p.ProcessId,
                                 p.Description,
                                 p.StartedOn,
                                 p.StartedBy,
                                 p.FinishedOn,
                                 p.FinishedBy,
                                 p.PlannedFinish,
                                 p.PlannedStart,
                                 fin.Name,
                                 fin.Surname,
                                 StarterName = star.Name, // <-- Creating alias
                                 StarterSurname = star.Surname // <-- Creating alias
                             } into grp
                             orderby grp.Key.ProcessId descending
                             select new Process
                             {
                                 ProcessId = grp.Key.ProcessId,
                                 Description = grp.Key.Description,
                                 StartedOn = grp.Key.StartedOn,
                                 StartedBy = grp.Key.StartedBy,
                                 StartedByName = grp.Key.StarterName + " " + grp.Key.StarterSurname,
                                 FinishedOn = grp.Key.FinishedOn,
                                 FinishedBy = grp.Key.FinishedBy,
                                 FinishedByName = grp.Key.Name + " " + grp.Key.Surname,
                                 PlannedStart = grp.Key.PlannedStart,
                                 PlannedFinish = grp.Key.PlannedFinish,
                                 HandlingStatus = grp.Where(ph=>ph.ha.IsCompleted == null && ph.ha.HandlingId >0).Count().ToString()
                             });
0 голосов
/ 12 февраля 2019

Я не уверен, насколько это будет полезно, потому что это перевод вашего SQL, и ваш LINQ, похоже, не связан с вашим SQL, но у меня есть:

var ans = from p in db.JDE_Processes
          join uuu in db.JDE_Users on p.FinishedBy equals uuu.UserId into uuuj
          from uuu in uuuj.DefaultIfEmpty()
          join h in db.JDE_Handlings on p.ProcessId equals h.ProcessId into hj
          from h in hj
          group new { p, h } by new { p.ProcessId, p.Description, p.StartedOn, p.StartedBy, p.FinishedOn, p.FinishedBy, p.PlannedFinish, p.PlannedStart } into phg
          select new {
              phg.Key.ProcessId,
              phg.Key.Description,
              phg.Key.StartedOn,
              phg.Key.StartedBy,
              phg.Key.FinishedOn,
              phg.Key.FinishedBy,
              phg.Key.PlannedFinish,
              phg.Key.PlannedStart,
              HandlingStatus = phg.Where(ph => ph.h.IsCompleted == null).Count()
          };
...