EF Core 2.1.4 Включить выполняет ВНУТРЕННЕЕ СОЕДИНЕНИЕ по дополнительным отношениям - PullRequest
0 голосов
/ 17 января 2019

У меня возникли проблемы с включением в запрос сущности, связанной с сущностью, с помощью метода Include.

var array = this.DbContext.Set<CustomerBranchOffice>()
.Where(x => 1 == 1) //JUST FOR THE EXAMPLE
.Include(x => x.CustomerWebSiteBrand)
.ToArray();

Связанный объект CustomerWebSiteBrand в CustomerBranchOffice может быть нулевым, если в таблице CustomerSiteBrand нет совпадений. Но метод Include всегда выполняет INNER JOIN, а не желаемый LEFT JOIN. Это фильтрует мне все строки CustomerBranchOffice, которые не соответствуют INNER JOIN.

Таблицы сервера SQL следующие:

    CREATE TABLE dbo.Customers
    (
        Id INT NOT NULL PRIMARY KEY IDENTITY,
        Name VARCHAR(100) NOT NULL,
        WebSite VARCHAR(100) NULL
    )

    CREATE TABLE dbo.Brands
    (
        BrandCode VARCHAR(5) NOT NULL PRIMARY KEY,
        Name VARCHAR(100) NOT NULL
    )

    CREATE TABLE dbo.CustomerBranchOffices
    (
        Id INT NOT NULL PRIMARY KEY IDENTITY,
        IdCustomer INT NOT NULL,
        Location VARCHAR(100) NOT NULL,
        BrandCode  VARCHAR(5) NOT NULL
        CONSTRAINT FK_CustomerBranchOffices_Brands FOREIGN KEY (BrandCode) REFERENCES dbo.Brands(BrandCode),
        CONSTRAINT FK_CustomerBranchOffices_Brands FOREIGN KEY (CustomerId) REFERENCES dbo.Customers(Id)
    )

    CREATE TABLE dbo.CustomerWebSiteBrands
    (
        Id NOT NULL PRIMARY KEY IDENTITY,
        CustomerId INT NOT NULL,
        BrandCode VARCHAR(5) NOT NULL,
        BrandWebSiteUrl VARCHAR(100) NOT NULL
        UNIQUE (CustomerId, BrandCode),
        CONSTRAINT FK_CustomerWebSiteBrands_Brands FOREIGN KEY (BrandCode) REFERENCES dbo.Brands(BrandCode),
        CONSTRAINT FK_CustomerWebSiteBrands_Brands FOREIGN KEY (CustomerId) REFERENCES dbo.Customers(Id)
    )

Существуют следующие сущности и отображения:

public class CustomerBranchOffice
{
    public int Id { get; set; }

    public int IdCustomer { get; set; }

    public string Location { get; set; }

    public string BrandCode { get; set; }

    public CustomerWebSiteBrand CustomerWebSiteBrand { get; set; }
}

public CustomerBranchOfficeMap(EntityTypeBuilder<CustomerBranchOffice> entityBuilder)
{
    entityBuilder.HasKey(x => x.Id);

    entityBuilder.Property(x => x.IdCustomer)
        .HasColumnName("IdCustomer")
        .HasColumnType("INTEGER")
        .IsRequired();

    entityBuilder.Property(x => x.Location)
        .HasColumnName("Location")
        .HasColumnType("VARCHAR(100)");

    entityBuilder.Property(x => x.BrandCode)
            .HasColumnName("BrandCode")
            .HasColumnType("VARCHAR(5)")
            .IsRequired();

    entityBuilder.HasOne(x => x.CustomerWebSiteBrand)
        .WithOne(x => x.CustomerBranchOffices)
        .HasForeignKey(x => new { x.IdCustomer, x.BrandCode } }) // The join is performed using these two properties (NOT NULLABLES)
        .HasPrincipalKey(x => new { x.IdCustomer, x.BrandCode });
}

public class CustomerWebSiteBrand
{
    public int Id { get; set; }

    public int IdCustomer { get; set; }

    public string BrandCode { get; set; }

    public string BrandWebSiteUrl { get; set; }

    public ICollection<CustomerBranchOffice> CustomerBranchOffices { get; set; }
}

public CustomerWebSiteBrandMap(EntityTypeBuilder<CustomerWebSiteBrand> entityBuilder)
{
    entityBuilder.HasKey(x => x.Id);

    entityBuilder.Property(x => x.IdCustomer)
        .HasColumnName("IdCustomer")
        .HasColumnType("INTEGER")
        .IsRequired();

    entityBuilder.Property(x => x.BrandCode)
            .HasColumnName("BrandCode")
            .HasColumnType("VARCHAR(5)")
            .IsRequired();

    entityBuilder.Property(x => x.BrandWebSiteUrl)
            .HasColumnName("BrandWebSiteUrl")
            .HasColumnType("VARCHAR(100)")
            .IsRequired();

    entityBuilder.HasMany(x => x.CustomerBranchOffices)
        .WithOne(x => x.CustomerWebSiteBran)
        .HasForeignKey(x => new { x.IdCustomer, x.BrandCode } }) // The join is performed using these two properties (NOT NULLABLES)
        .HasPrincipalKey(x => new { x.IdCustomer, x.BrandCode });
}

Как видите, связь выполняется с использованием свойств IdCustomer и BranchCode. Оба требуются в обоих объектах.

Я попытался использовать new { IdCustomer = (int?)x.IdCustomer, x.BrandCode } в конфигурации HasForeignKey и HasPrincipalKey, но все равно ORM выполняет INNER JOIN. Есть ли способ заставить LEFT JOIN с помощью метода Include?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...