Entity Framework Core 中值对象的额外连接查询
Extra join in query for value objects in Entity Framework Core
在Entity Framework Core 3.1.3中,我使用了值对象特性。在查询端,问题是 T-SQL 中存在额外的左连接。这种额外的连接会导致性能方面的问题。在下面的代码中,Student 是一个实体类型,Address class 是一个值类型.
实体
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string Street { get; set; }
public string City { get; set; }
public string ZipCode { get; set; }
}
DbContext
public class ApplicationDbContext : DbContext
{
public DbSet<Student> Students { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Student>().OwnsOne(e => e.Address);
base.OnModelCreating(builder);
}
}
Entity Framework查询
var list = _dbContext.Students.ToList();
为此 EF 查询生成的 T-SQL:
SELECT [s].[Id], [s].[Name], [t].[Id], [t].[Address_City],
[t].[Address_Street], [t].[Address_ZipCode]
FROM [Students] AS [s]
LEFT JOIN (
SELECT [s0].[Id], [s0].[Address_City],
[s0].[Address_Street], [s0].[Address_ZipCode]
FROM [Students] AS [s0]
WHERE [s0].[Address_ZipCode] IS NOT NULL OR
([s0].[Address_Street] IS NOT NULL OR
[s0].[Address_City] IS NOT NULL)
) AS [t] ON [s].[Id] = [t].[Id]
您提到的关系是 "Owned" 类型。查询父对象时始终包含拥有的类型。有关详细信息,请参阅 here。
您可以使用 'HasOne' 关系来避免这种情况。
这是 EF Core 3.0 新查询处理管道引入的错误,很可能与以下重大更改有关 Dependent entities sharing the table with the principal are now optional,该更改本应修复一些用户请求的场景,但实际上破坏了许多其他场景。
目前由 #18299: Query on owned entity produces overly complicated SQL 跟踪,不幸的是看起来不会在 3.1 中修复,因此人们希望等待 5.0 发布。与此同时,你对此无能为力。
在Entity Framework Core 3.1.3中,我使用了值对象特性。在查询端,问题是 T-SQL 中存在额外的左连接。这种额外的连接会导致性能方面的问题。在下面的代码中,Student 是一个实体类型,Address class 是一个值类型.
实体
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string Street { get; set; }
public string City { get; set; }
public string ZipCode { get; set; }
}
DbContext
public class ApplicationDbContext : DbContext
{
public DbSet<Student> Students { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Student>().OwnsOne(e => e.Address);
base.OnModelCreating(builder);
}
}
Entity Framework查询
var list = _dbContext.Students.ToList();
为此 EF 查询生成的 T-SQL:
SELECT [s].[Id], [s].[Name], [t].[Id], [t].[Address_City],
[t].[Address_Street], [t].[Address_ZipCode]
FROM [Students] AS [s]
LEFT JOIN (
SELECT [s0].[Id], [s0].[Address_City],
[s0].[Address_Street], [s0].[Address_ZipCode]
FROM [Students] AS [s0]
WHERE [s0].[Address_ZipCode] IS NOT NULL OR
([s0].[Address_Street] IS NOT NULL OR
[s0].[Address_City] IS NOT NULL)
) AS [t] ON [s].[Id] = [t].[Id]
您提到的关系是 "Owned" 类型。查询父对象时始终包含拥有的类型。有关详细信息,请参阅 here。
您可以使用 'HasOne' 关系来避免这种情况。
这是 EF Core 3.0 新查询处理管道引入的错误,很可能与以下重大更改有关 Dependent entities sharing the table with the principal are now optional,该更改本应修复一些用户请求的场景,但实际上破坏了许多其他场景。
目前由 #18299: Query on owned entity produces overly complicated SQL 跟踪,不幸的是看起来不会在 3.1 中修复,因此人们希望等待 5.0 发布。与此同时,你对此无能为力。