EF Core Navigation Property Include 使用左连接而不是内连接

Posted

技术标签:

【中文标题】EF Core Navigation Property Include 使用左连接而不是内连接【英文标题】:EF Core Navigation Property Include uses Left Join instead of Inner Join 【发布时间】:2020-06-06 15:45:58 【问题描述】:

在我的 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 总是为任何团队创建并且不可为空,那么它不应该使用内部联接吗?

【问题讨论】:

【参考方案1】:

where 子句“t => t.Id == teamId && t.TeamSettings != null”怎么样。这应该与 Includes 命令一起实现。这样你就可以强制它表现得像一个内部连接。

【讨论】:

【参考方案2】:

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

因此 EF Core 不支持它([Team.TeamSettings] 上的[Required] 属性被忽略)。这在文档的Required and optional relationships 部分中有所解释:

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

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

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

【讨论】:

以上是关于EF Core Navigation Property Include 使用左连接而不是内连接的主要内容,如果未能解决你的问题,请参考以下文章

EF Core 快速上手——EF Core 入门

EF Core的安装EF Core与数据库结合

EF Core 迁移过程遇到EF Core tools version版本不相符的解决方案

从 EF Core 5 迁移到 EF Core 6 时出错

ef core 子对象集合插入顺序

EF Core 迁移过程遇到EF Core tools version版本不相符的解决方案