我正在尝试使用以下方法实现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中的相同行。映射条件可用于 区分这些类型映射到的行。
任何想法我做错了什么?
答案 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);
});
我不相信这是最好的方式,但至少它是有效的。