如何在EF Core v3中进行左外部联接

时间:2020-02-21 15:12:37

标签: entity-framework-core ef-core-3.0 ef-core-3.1

我一直在尝试使用GroupJoin语句在两个表上进行左外部联接,以便我可以获取表A中的行的列表,而表A中的表B中没有任何项目。但是,我不断收到异常< / p>

  Exception found: Processing of the LINQ expression 'DbSet<People>
      .GroupJoin(
          outer: DbSet<RiskGroup>,
          inner: person => (Nullable<int>)person.Id,
          outerKeySelector: risk => risk.AssessorId,
          innerKeySelector: (person, risks) => new {
              person = person,
              risks = risks
                  .DefaultIfEmpty()
           })' by 'NavigationExpandingExpressionVisitor' failed. 

似乎暗示在EF Core v3中是不可能的。有谁知道如何解决这个问题,或者我的LINQ在下面是不正确的:

    var Ids = destContext.People.GroupJoin(destContext.RiskGroup,
        person => person.Id,
        risk => risk.AssessorId,
        (person, risks) => new { person, risks = risks.DefaultIfEmpty() }).ToList();

我试图在人员表中查找所有在RiskGroup表中没有行的行。

1 个答案:

答案 0 :(得分:0)

我自己为此感到挣扎,希望对您有帮助

对于初学者来说,我将保持简单。只是发现如果我们这样做会更容易 这是每个开发人员都会遇到的公司和地址

第一个表(公司)是我们可以拥有多个记录的表 第二个表(地址)有一个记录

         company => company.AddressId,
         address => address.AddressId,

因此,我们使用地址的addressId进行查询,我一直使用tableNameId,它使内容更易于阅读

因此对于GroupJoin,您现在需要输出,以便以后在查询中使用。

(company, address) = new (company, address) 

现在您需要一个SelectMany-这就是每个人都搞砸的地方 您需要记录公司中是否为空

 s.address.DefaultIfEmpty(),

和SelectMany的输出

 (s, address) => new { company = s.company, address });

注意,非常重要-公司必须是s.company-不只是公司,否则LEFT JOIN将不会出现。

     var a = context.Companys.GroupJoin(context.Addresses,
             company => company.AddressId,
             address => address.AddressId,
             (company, address) => new { company, address })
             .SelectMany(s => s.address.DefaultIfEmpty(),
                        (s, address) => new { company = s.company, address });
    var outA = a.ToList();

针对您的特定问题

 var a = destContext.People.GroupJoin(destContext.RiskGroup,
             person => person.Id,
             risk => risk.AssessorId,
             (person, risk) => new { person, risk })
             .SelectMany(s => s.risk.DefaultIfEmpty(),
                        (s, risk) => new { person = s.person, risk })
             .Where(x => x.AssesorId == null);
        var outA = a.ToList();

尝试一下,看看是否能满足需要