实体框架:软删除和每种类型的表

时间:2015-02-13 09:14:22

标签: c# .net entity-framework

我正在尝试使用以下方法实现Soft Delete模式: https://stackoverflow.com/a/18985828/213725

但是我很难为Table Per Type继承实现它。假设我将Entity映射到表“Entity”,将其后代ConcreteEntity映射到表“ConcreteEntity”。我在“实体”表中有IsDeleted列来指定实体是否“已删除”。 我在OnModelCreating尝试做的事情如下:

modelBuilder.Entity<Entity>()
    .Map<Entity>(m =>
    {
        m.ToTable("Entity");
        m.Requires("IsDeleted").HasValue(false);
    })
    .Map<ConcreteEntity>(m =>
    {
        m.ToTable("ConcreteEntity");
    });

我不工作。我收到以下错误:

  

(59,10):错误3032:从行开始映射片段时出现问题   59,142:EntityTypes Entity,ConcreteEntity正被映射到   表Entity中的相同行。映射条件可用于   区分这些类型映射到的行。

任何想法我做错了什么?

2 个答案:

答案 0 :(得分:1)

软删除技术使用鉴别器字段来确保EF始终过滤掉软删除的实体。但是鉴别器字段是为了使用Table-Per-Hierarchy实现继承而设计的。我相信EF在它到达ToTable("ConcreteEntity")

之前就已经崩溃了

这是因为EF解释了这一行:m.Requires("IsDeleted").HasValue(false);意味着您正在使用TPH,并且通过向SQL添加IsDeleted=false将从单个表中检索实体。我不相信EF会让你将鉴别器和Table-Per-Type继承结合起来。

答案 1 :(得分:1)

事实证明,使用鉴别器组合TPT和软删除模式非常棘手。

因此,为了使其工作,我将Entity抽象并移动IsDeleted列到ConcreteEntity表。然后我按如下方式更改了映射:

modelBuilder.Entity<Entity>().Map(m => m.ToTable("Entity"));

modelBuilder.Entity<ConcreteEntity>().Map(m => 
{
    m.ToTable("ConcreteEntity");
    m.Requires("IsDeleted").HasValue(false);
});

我不相信这是最好的方式,但至少它是有效的。