在查询中使用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
?