使用 C# EF Core 返回具有空子级的父级。包括

Dav*_*win 3 c# entity-framework entity-framework-core

我们的目标是使用 Entity Framework Core 和 .Include(...)扩展方法返回具有子级的对象集合,其中一些子级将为空。

我们有一个表的项目与C#模型项目和表位置用C#模型位置。

每个项目都有一个或零个Location对象,对象如下所示:

public class Project
{
     public string LocationId { get; set; }
     public Location Location { get; set; }
}

public class Location
{
     public string LocationId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

数据库设置如下所示:

        modelBuilder.Entity<Location>(entity =>
        {
            entity.HasKey(location => location.LocationId);
            entity.ToTable("Locations");
        });
        modelBuilder.Entity<Project>(entity =>
        {                
            entity.HasOne(project => project.Location).WithMany()
            .HasForeignKey(x => x.LocationId);                
            entity.ToTable("Projects");

        });
Run Code Online (Sandbox Code Playgroud)

我们创建的查询是:

var projects = dbContext.Projects.Include(x => x.Location);
Run Code Online (Sandbox Code Playgroud)

当我们期望LEFT OUTER JOIN时,EF 生成的 SQL 包含一个LEFT JOIN:

SELECT [project].[LocationId] 
FROM [Projects] AS [project] 
LEFT JOIN [Locations] AS [c] ON [project].[LocationId] = [c].[LocationId]
Run Code Online (Sandbox Code Playgroud)

结果是只返回带有位置的项目。我们想要所有项目及其位置。

从这个链接我了解到,.Include(...)决定执行 LEFT JOIN 或 LEFT OUTER JOIN 取决于外键的可空性:

Code First 根据外键的可空性推断关系的多样性。如果该属性可为空,则该关系将注册为可选。

因为这不是发生的事情,所以缺少一些东西。

无论是否填充它们的位置,都需要进行哪些修改才能返回所有项目?

谢谢!

小智 6

您可以DefaultIfEmpty()在 之后使用方法Include()。

例如:

var projects = dbContext.Projects.Include(x => x.Location).DefaultIfEmpty()...;
Run Code Online (Sandbox Code Playgroud)


SBF*_*ies -1

在 T-SQL 中,左连接和左外连接是同一回事。Outer 关键字是可选的。您给出的查询将返回所有产品,无论它们是否有位置。测试一下看看。

有关更多详细信息,请参阅:SQL Server 中的 LEFT JOIN 与 LEFT OUTER JOIN