【问题标题】:EF Core Navigation Property Include uses Left Join instead of Inner JoinEF Core Navigation Property Include 使用左连接而不是内连接
【发布时间】: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 总是为任何团队创建并且不可为空,那么它不应该使用内部联接吗?

【问题讨论】:

    标签: c# sql-server asp.net-core .net-core entity-framework-core


    【解决方案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

      【讨论】:

        猜你喜欢
        • 2017-12-21
        • 1970-01-01
        • 2012-07-21
        • 2017-07-11
        • 1970-01-01
        • 2018-07-09
        • 2021-05-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多