使用具有复合键的基表使用列和常量值

时间:2016-05-19 17:24:31

标签: c# entity-framework

我正在尝试在EF中为以下模式建模:

enter image description here

TEntity包含每个TFile的记录:EntityIdFileId,而EntityType是一个表示TFile记录的常量值 - 还有其他以这种方式工作的表格。

TEntityFile是一个查找表,我设法对此进行了建模,但已将其包含在内,以演示我必须配置/使用TEntity的不同方法。此表将存储不同实体的查找到其文件。

我目前的配置:

// TEntity
EntityTypeConfiguration<TEntity> entityConfig = modelBuilder.Entity<TEntity>()
    .ToTable("TEntity")
    .HasKey(x => x.EntityGuid);

// TFile
EntityTypeConfiguration<TFile> fileConfig = modelBuilder.Entity<TFile>()
   .ToTable("TFile")
   .HasKey(x => x.FileId);

// TEntityFile
EntityTypeConfiguration<TEntityFile> entityFileConfig = modelBuilder.Entity<TEntityFile>()
    .ToTable("TEntityFile")
    .HasKey(x => new { x.EntityGuid, x.FileId });

entityFileConfig
    .HasRequired(x => x.File)
    .WithMany()
    .HasForeignKey(x => x.FileId);

entityFileConfig
    .HasRequired(x => x.Entity)
    .WithMany()
    .HasForeignKey(x => x.EntityGuid);

由于每个TFile都是TEntity,我想以这种方式为课程建模:

public class TFile : TEntity { }

我的问题在于告诉EF TFileTEntity的关系,考虑到它使用以下字段进行映射:

  • FileId = EntityId
  • EntityType = 1

在它生成的查询中,它希望EntityGuid上的列TFile加入。我可以用这种方式使用EF来建模这个模式吗?如果是这样,我需要更改哪些内容才能让EF了解如何将TFile行与其对应的TEntity行合并。

1 个答案:

答案 0 :(得分:1)

底线是您的数据库架构未规范化,您无法创建使用数据库架构描述的概念模型,如下所示:

  • 数据库架构允许TEntityTFile之间的N:N关系 虽然你的描述看起来好像你想要一个1:0..1关系 - 除非你对TEntityFile的每个PK字段都有唯一约束,但为什么要有这个表呢? EF概念模型也不了解唯一约束(至少在EF6及以下),因此即使使用唯一约束,也无法创建所需的概念模型。
  • 由于数据之间的重复,数据库未正常化 可以导致的TEntity.EntityIdTEntityFile.FileId 插入/更新/删除异常(例如,您可以更新 TEntity.EntityId但不删除/修改相应的 TEntityFile记录) - 我认为这违反了2NF

根据你的描述,听起来你想要EntityType作为你的鉴别器(TPH违反3NF,顺便提一下,每个层次结构(TPH)继承,但很多人认为它是可接受的)但是你将需要为每个定义的类型单独的FK字段(例如:EntityId将替换为FileId的{​​{1}}字段。

另一种方法是使用Table-Per-Type(TPT)继承 - 这样就不需要EntityType == 1鉴别器列,而是could reduce performance if joining from TEntity to TFile and other inherited entities