EF Core 2.1.4 Include对可选关系执行INNER JOIN

时间:2019-01-17 12:14:15

标签: c# entity-framework-core

在查询中使用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。这是在过滤所有CustomerBranchOfficeINNER 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 });
}

如您所见,该关系是使用属性IdCustomerBranchCode执行的。这两个实体都需要。

我尝试在new { IdCustomer = (int?)x.IdCustomer, x.BrandCode }HasForeignKey配置中使用HasPrincipalKey,但仍然,ORM执行INNER JOIN。有什么方法可以使用LEFT JOIN方法强制Include

0 个答案:

没有答案