EF核心导航属性包括使用左联接而不是内联接

时间:2020-02-22 11:34:05

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

在我的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始终为任何团队创建,并且不能为空,因此不应该使用内部联接吗?

2 个答案:

答案 0 :(得分:3)

关系数据库无法实施一对一(即两端都是必需的)关系,因为没有标准的FK约束可以阻止删除从属记录(在您的情况下为TeamSettings)。

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

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

由于FK始终在从属端,因此从技术上讲,这意味着您只能控制从属是否可以不存在委托人而存在。但是委托人可以永远存在而不受依赖。

很快,关系依赖项总是 可选,因此是left join

答案 1 :(得分:1)

where子句如何?“ t => t.Id == teamId && t.TeamSettings!= null”。这应该与Includes命令一起实现。这样,您就可以强制它表现得像内部联接。