1

我还没有在 linq 中进行 LEFT JOIN,而且我非常卡住。

目前,我有这个:

var results = (from csr
                               in _context.project_sprint_resource
                           join pr in _context.project_resource
                               on csr.ProjectResourceId equals pr.Id
                            join prpa in _context.project_resource_person_allocation
                                on pr.Id equals prpa.ProjectResourceId
                                where csr.ProjectSprintId == sprintId
                           select new SprintResourceDto
                               {
                                   SprintId = csr.ProjectSprintId,
                                   ProductiveHours = pr.ExpectedProductiveHours,
                                   ProjectResourceId = pr.Id,
                                   ResourceTypeId = pr.ResourceTypeId,
                                   ResourceType = new ReferenceTypeDto
                                       {
                                           Description = pr.resource_type.Description,
                                           Id = pr.resource_type.Id
                                       },
                                   AssignedHours = pr.ExpectedProductiveHours,
                                   Person = new PersonDto
                                       {
                                           Id = prpa.Id,
                                           Firstname = prpa.person.Firstname,
                                           Surname = prpa.person.Surname
                                       },
                                       PersonId = prpa.PersonId
                               }).ToList();
            return results.ToList();

我需要更改它,以便“_context.project_resource_person_allocation 中的 prpa”成为左连接,因为该表可能没有匹配的行。

看起来需要一个INTO,但我看到的例子并不清楚如何。

我的另一个选择可能是以某种方式在两个查询中进行?但是,我是一个 SQL 人,但是,发现很难掌握如何在 linq 中进行左连接。

编辑:我取得了一些进展,但有一个最后的问题。我已经修改了查询,似乎我得到了正确的行,但是......在没有右侧行(左连接)的情况下,它崩溃了,因为我无法将 NULL 分配给我的 Person属性(这是我创建的一个类):

        var results = (from csr
                           in _context.project_sprint_resource
                       join pr in _context.project_resource
                           on csr.ProjectResourceId equals pr.Id
                       join prpa in _context.project_resource_person_allocation
                           on pr.Id equals prpa.ProjectResourceId into sub
                       from subq in sub.DefaultIfEmpty()
                       where csr.ProjectSprintId == sprintId
                       select new SprintResourceDto
                           {
                               SprintId = csr.ProjectSprintId,
                               ProductiveHours = pr.ExpectedProductiveHours,
                               ProjectResourceId = pr.Id,
                               AssignedHours = pr.ExpectedProductiveHours,
                               ResourceTypeId = pr.ResourceTypeId,
                               PersonId = subq != null ? subq.PersonId : (int?)null,
                               ResourceStartDate = pr.StartDate,
                               ResourceEndDate = pr.EndDate,
                               Deleted = csr.Deleted.HasValue,
                               ResourceType = new ReferenceTypeDto
                                   {
                                       Description = pr.resource_type.Description,
                                       Id = pr.resource_type.Id
                                   },
                               Person = null
                                //= subq != null ? new PersonDto
                                //   {
                                //       Id = subq != null ? subq.Id : 0,
                                //       Firstname = subq != null ? subq.person.Firstname : "",
                                //       Surname = subq != null ? subq.person.Surname : ""
                                //   } : null,
                           });
        return results.ToList();
    }
    catch (Exception e)
    {
        var ne = e;
        return null;
    }

当我尝试将 NULL 分配给 Person 时发生错误。我收到一条错误消息:

无法创建类型为“SharedObjects.EntityObjects.PersonDto”的空常量值。此上下文仅支持实体类型、枚举类型或原始类型。

PersonDto 对象的定义如下:

public class PersonDto
{
    public int Id { get; set; }
    public string Firstname { get; set; }
    public string Surname { get; set; }
    public decimal GrossSalary { get; set; }
    public string FullName
    {
        get { return string.Format("{0} {1}", Firstname, Surname); }
    }
}
4

2 回答 2

1

嘿,你能试试这个,请告诉我你得到了什么?

var results = (from csr in _context.project_sprint_resource
               join pr in _context.project_resource
                   on csr.ProjectResourceId equals pr.Id
               join prpa in _context.project_resource_person_allocation
                   on pr.Id equals prpa.ProjectResourceId into sub
               from subq in sub.DefaultIfEmpty()
               where csr.ProjectSprintId == sprintId
               select new { csr = csr, pr = pr, subq = subq}).AsEnumerable(x => 
                   select new SprintResourceDto
                       {
                           SprintId = x.csr.ProjectSprintId,
                           ProductiveHours = x.pr.ExpectedProductiveHours,
                           ProjectResourceId = x.pr.Id,
                           AssignedHours = x.pr.ExpectedProductiveHours,
                           ResourceTypeId = x.pr.ResourceTypeId,
                           PersonId = x.subq != null ? x.subq.PersonId : (int?)null,
                           ResourceStartDate = pr.StartDate,
                           ResourceEndDate = x.pr.EndDate,
                           Deleted = x.csr.Deleted.HasValue,
                           ResourceType = new ReferenceTypeDto
                               {
                                   Description = x.pr.resource_type.Description,
                                   Id = x.pr.resource_type.Id
                               },
                           Person = x.subq != null ? new PersonDto
                               {
                                   Id = x.subq.Id,
                                   Firstname x.subq.person.Firstname
                                   Surname = subq.person.Surname
                               } : null
                       });
    return results.ToList();
}
catch (Exception e)
{
    var ne = e; // What on earth is this by the way?
    return null;
}
于 2013-07-04T08:12:44.527 回答
1

我发现了这个问题。检查 NULL 是问题所在。似乎子查询永远不会为 NULL。相反,检查 subq.Count() > 0

它似乎创建了项目的“列表”,但由于我正在尝试“左连接”,它只是将任何项目添加到子中。

添加 .Count 检查解决了它,我得到了完美的结果。

于 2013-07-05T04:03:56.060 回答