如何在 EF Core v3 中执行左外连接

Al_*_*l_B 6 entity-framework-core ef-core-3.0 ef-core-3.1

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

  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. 
Run Code Online (Sandbox Code Playgroud)

这似乎意味着在 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();
Run Code Online (Sandbox Code Playgroud)

我试图找到 person 表中在 RiskGroup 表中没有行的所有行。

Law*_*man 6

我自己也曾为此苦苦挣扎,我想看看这是否对您有帮助

好的,对于初学者来说,我将保持简单。如果我们这样做的话,就会发现事情会变得更容易,这是每个开发人员都会遇到的公司并解决的问题

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

         company => company.AddressId,
         address => address.AddressId,
Run Code Online (Sandbox Code Playgroud)

所以我们使用地址的addressId进行查询,我总是使用tableNameId,这样更容易阅读

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

(company, address) = new (company, address) 
Run Code Online (Sandbox Code Playgroud)

现在你需要一个 SelectMany - 这就是让每个人都陷入困境的原因,当 Company 中存在空值时,你需要一个记录

 s.address.DefaultIfEmpty(),
Run Code Online (Sandbox Code Playgroud)

以及 SelectMany 的输出

 (s, address) => new { company = s.company, address });
Run Code Online (Sandbox Code Playgroud)

注意,非常重要 - 公司必须是 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();
Run Code Online (Sandbox Code Playgroud)

针对您的具体问题

 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();
Run Code Online (Sandbox Code Playgroud)

尝试一下,看看你是否得到了你需要的东西