展平复合实体

时间:2016-05-17 21:08:20

标签: c# sql-server entity-framework ef-fluent-api

是否可以在实体框架中将两表关系扁平化为单个实体?

具体而言,(例如简化)给定以下两个定义1-1关系的表

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;}
}

请注意,表Bar中只有一个字段映射到FlatFoo

备注

  • 实际的表格更大。
  • 由于Bar中的文本值可能会变大,因此会快速填充索引页,因此有两个表可以更快地对Foo.Id和Foo.Name进行索引搜索。
  • 我查看了Split Entities,但它要求两个表具有相同的主键。
  • 我查看了复杂类型,但它以相反的方式工作,采用平面表并拆分成复合实体。
  • 我希望使用Fluent API来执行映射。

您可以在展平两个表和单个实体之间的映射方面提供任何帮助吗?

更新

是的,视图将有助于获得一个扁平的实体,但后来我没有从表映射到实体。同样,从另一方面来说,我知道可以映射到非公共组合并以这种方式公开财产。但是,我更感兴趣的是学习EF流畅的API是否足够灵活,可以直接处理映射,而不是解决特定问题。

不幸的是,在这里(工作中)有任何建议向数据库添加除表之外的任何东西(基本上包括视图)。通常会指出,这样做会增加额外的维护点,增加对支持的培训,增加基本CRUD的复杂性以及其他不学习可用工具的借口。这充其量是愚蠢的,但这是我必须要处理的事情。 :(

所以,作为一个学习点,我是否有可能做这个看似基本的任务,即使用EF直接将两个任意表中的字段映射到一个实体,首选流畅的API?

1 个答案:

答案 0 :(得分:3)

实体框架没有提供将一个实体映射到两个表的方法,然后以您描述的方式从列中选择,除非这些表共享一个公共密钥。正如评论中提到的,最简单的解决方案是创建一个View并将实体映射到该。

public class FlatFooMap : EntityTypeConfiguration<FlatFoo>
{
    public FlatFooMap ()
    {
        ToTable("vwFlatFoo");
        HasKey(t => t.Id);                        
    }
}