EF Core Navigation Свойство Включить использует левое соединение вместо внутреннего соединения - PullRequest
1 голос
/ 22 февраля 2020

В моем проекте 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 создается всегда для какая-нибудь команда и не может быть nullable, разве не следует использовать внутреннее соединение?

Ответы [ 2 ]

2 голосов
/ 22 февраля 2020

Реляционные базы данных не могут навязывать взаимно-однозначные (т. Е. Требуются оба конца), потому что никакое стандартное ограничение FK не может помешать удалению зависимой записи (TeamSettings в вашем случае).

Следовательно, EF Core не поддерживает его (атрибут [Required] в [Team.TeamSettings] игнорируется). Это как-то объясняется в разделе Обязательные и необязательные отношения документации:

Вы можете использовать Fluent API для настройки, является ли связь обязательной или необязательной. В конечном итоге это определяет, является ли свойство внешнего ключа обязательным или необязательным.

Поскольку FK всегда находится на зависимой стороне, технически это означает, что вы можете контролировать только то, может ли существовать зависимый без основной суммы. Но принципал всегда может существовать без зависимости.

Короче говоря, зависимые отношения всегда необязательны, следовательно, left join.

1 голос
/ 24 февраля 2020

Как насчет , где предложение"t => t.Id == teamId && t.TeamSettings! = Null". Это должно быть реализовано вместе с командой «Включает». Таким образом вы заставляете его вести себя как внутреннее соединение.

...