展平复合实体
Flatten composite entities
是否可以在 Entity Framework 中将两个 table 关系扁平化为一个实体?
具体来说,(例如简化)给定以下两个定义 1-1 关系的 table
create table Foo
(
Id int not null identity (1, 1)
constraint PK_Foo_Id primary key (Id),
Name nvarchar(64) not null,
BarId int not null
constraint FK_Bar_Foo foreign key (BarId) references Bar (Id)
)
create table Bar
(
Id int not null identity (1, 1)
constraint PK_Bar_Id primary key (Id),
Value nvarchar(max) not null
)
我可以轻松地将其映射到这样的实体
public class Foo
{
public int Id { get; set;}
public string Name { get; set;}
public Bar Bar { get; set;}
}
public class Bar
{
public int Id { get; set;}
public string Value { get; set;}
}
但我想映射到单个扁平实体
public class FlatFoo
{
public int Id { get; set;}
public string Name { get; set;}
public string Value { get; set;}
}
请注意,只有 table Bar 中的一个字段映射到 FlatFoo
备注
- 实际 table 更大。
- 由于 Bar 中的文本值可以变大,它会很快填满索引页面,因此有两个 tables 用于针对 Foo.Id 和 Foo.Name 进行更快的索引搜索。
- 我查看了拆分实体,但它要求两个 table 具有相同的主键。
- 我看过复杂类型,但它以相反的方式工作,采用平面 table 并拆分为复合实体。
- 我希望使用 Fluent API 来执行映射。
您能否提供任何帮助来展平两个 table 与单个实体之间的映射?
更新
是的,视图将用于获得平面实体,但我不会从 table 映射到实体。同样,从另一方面来看,我知道可以映射到非 public 组合并以这种方式公开 属性。但是,与解决特定问题相比,我更感兴趣的是了解 EF fluent API 是否足够灵活以直接处理映射。
不幸的是,这里(在工作中)对任何将 tables 以外的任何内容添加到数据库(包括视图在内的基本内容)的任何建议都存在相当大的阻力。通常指出,这样做会增加额外的维护点、增加支持培训、增加基本 CRUD 的复杂性以及不学习可用工具的其他借口。这充其量是愚蠢的,但这是我必须处理的事情。 :(
那么,作为我的一个学习点,是否可以完成这个看似基本的任务,即使用 EF 将任意两个任意 table 的字段直接映射到一个实体中,流利 API 首选?
Entity Framework 不提供将一个实体映射到两个表然后按照您描述的方式从列中挑选的方法,除非这些表共享一个公共键。因此,如评论中所述,最简单的解决方案是创建一个视图并将实体映射到该视图。
public class FlatFooMap : EntityTypeConfiguration<FlatFoo>
{
public FlatFooMap ()
{
ToTable("vwFlatFoo");
HasKey(t => t.Id);
}
}
是否可以在 Entity Framework 中将两个 table 关系扁平化为一个实体?
具体来说,(例如简化)给定以下两个定义 1-1 关系的 table
create table Foo
(
Id int not null identity (1, 1)
constraint PK_Foo_Id primary key (Id),
Name nvarchar(64) not null,
BarId int not null
constraint FK_Bar_Foo foreign key (BarId) references Bar (Id)
)
create table Bar
(
Id int not null identity (1, 1)
constraint PK_Bar_Id primary key (Id),
Value nvarchar(max) not null
)
我可以轻松地将其映射到这样的实体
public class Foo
{
public int Id { get; set;}
public string Name { get; set;}
public Bar Bar { get; set;}
}
public class Bar
{
public int Id { get; set;}
public string Value { get; set;}
}
但我想映射到单个扁平实体
public class FlatFoo
{
public int Id { get; set;}
public string Name { get; set;}
public string Value { get; set;}
}
请注意,只有 table Bar 中的一个字段映射到 FlatFoo
备注
- 实际 table 更大。
- 由于 Bar 中的文本值可以变大,它会很快填满索引页面,因此有两个 tables 用于针对 Foo.Id 和 Foo.Name 进行更快的索引搜索。
- 我查看了拆分实体,但它要求两个 table 具有相同的主键。
- 我看过复杂类型,但它以相反的方式工作,采用平面 table 并拆分为复合实体。
- 我希望使用 Fluent API 来执行映射。
您能否提供任何帮助来展平两个 table 与单个实体之间的映射?
更新
是的,视图将用于获得平面实体,但我不会从 table 映射到实体。同样,从另一方面来看,我知道可以映射到非 public 组合并以这种方式公开 属性。但是,与解决特定问题相比,我更感兴趣的是了解 EF fluent API 是否足够灵活以直接处理映射。
不幸的是,这里(在工作中)对任何将 tables 以外的任何内容添加到数据库(包括视图在内的基本内容)的任何建议都存在相当大的阻力。通常指出,这样做会增加额外的维护点、增加支持培训、增加基本 CRUD 的复杂性以及不学习可用工具的其他借口。这充其量是愚蠢的,但这是我必须处理的事情。 :(
那么,作为我的一个学习点,是否可以完成这个看似基本的任务,即使用 EF 将任意两个任意 table 的字段直接映射到一个实体中,流利 API 首选?
Entity Framework 不提供将一个实体映射到两个表然后按照您描述的方式从列中挑选的方法,除非这些表共享一个公共键。因此,如评论中所述,最简单的解决方案是创建一个视图并将实体映射到该视图。
public class FlatFooMap : EntityTypeConfiguration<FlatFoo>
{
public FlatFooMap ()
{
ToTable("vwFlatFoo");
HasKey(t => t.Id);
}
}