首页 > 解决方案 > EF Core Navigation Property Include 使用左连接而不是内连接

问题描述

在我的 API 项目中,我有

public class Team
{
    [Key]
    public long Id { set; get; }
    [Required]
    public TeamSettings TeamSettings { get; set; }
}

public class TeamSettings
{
    [Key]
    [Required]
    [Column("TeamSettingsId")]
    public long Id { set; get; }
    [Required]
    [ForeignKey("TeamId")]
    public long TeamId { get; set; }
    [Required]
    public Team Team { set; get; }
}

当我使用

var team = await TeamRepo.GetAsync(t => t.Id == teamId, includes);

我可以在我的 SQL Server Profiler 上看到左连接而不是内连接。

我尝试删除注释并像这样流利:

modelBuilder.Entity<Team>()
                    .HasOne(t => t.TeamSettings)
                    .WithOne(ts => ts.Team)
                    .HasForeignKey<TeamSettings>(ts => ts.TeamId);

但是,我得到的只是一个左连接。

由于 TeamSettings 始终为任何团队创建并且不可为空,因此不应该使用内部联接吗?

标签: c#sql-serverasp.net-core.net-coreentity-framework-core

解决方案


关系数据库不能强制执行一对一(即两端都需要)关系,因为没有标准的 FK 约束可以阻止删除相关记录(TeamSettings在您的情况下)。

因此 EF Core 不支持它([Required]属性 on[Team.TeamSettings]被忽略)。这在文档的必需和可选关系 部分中有所解释:

您可以使用 Fluent API 来配置关系是必需的还是可选的。最终,这控制了外键属性是必需的还是可选的。

由于 FK 始终在依赖方,从技术上讲,这意味着您只能控制依赖项是否可以在没有主体的情况下存在。但是主体可以始终存在而没有依赖关系。

简而言之,关系依赖项始终是可选的,因此left join.


推荐阅读