我想用自定义鉴别器实现TPH(每个层次的表)。这是模型:
public class Event
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime Start { get; set; }
}
public class Appointment : Event
{
public TimeSpan Duration { get; set; }
}
我的自定义鉴别符应该在Duration
列中:如果是NULL
,则必须是Event
,否则是Appointment
。
但是在创建迁移步骤时出现此错误:
实体类型“事件”是层次结构的一部分,但未配置区分值。
我错了什么?以及如何启动和运行鉴别器?
这里是DbContext
:
public class ApplicationDbContext : DbContext
{
...
public DbSet<Event> Events { get; set; }
public DbSet<Appointment> Appointments { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
...
modelBuilder.Entity<Event>()
.HasDiscriminator<TimeSpan?>(nameof(Appointment.Duration))
.HasValue(null)
;
}
}
答案 0 :(得分:1)
您收到的错误最初是因为 Discriminator 的值不能为null。但是实际上还有另一个问题使其无法使用。
TPH中的每种实体类型(Event
和Appointment
)必须具有 Discriminator 的属性。
如果您未为 Discriminator 指定任何配置,则默认使用具有字符串类型的名为 Discriminator 的属性。此属性存储实体类型的名称,并用于检查行映射到的类型。
您可以保留 Discriminator 的配置(保留默认行为),也可以配置如下自定义项:
public class Event
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime Start { get; set; }
}
public class Appointment : Event
{
public TimeSpan Duration { get; set; }
}
public class ApplicationDbContext : DbContext
{
...
public DbSet<Event> Events { get; set; }
public DbSet<Appointment> Appointments { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
...
modelBuilder.Entity<Event>()
.HasDiscriminator<int>("discriminator")
.HasValue<Event>(1)
.HasValue<Appointment>(2);
}
}
注意:如果 Discriminator 的类型不是字符串,则对于层次结构中的每个实体类型,必须指定一个鉴别符值。 (如上面的代码所示)
但是,如果 Discriminator 的类型为字符串,则可以自动用实体类型名称填充。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
...
modelBuilder.Entity<Event>()
.HasDiscriminator<string>("discriminator")
.HasValue("e"); // "e" is the value of discriminator for Event type.
// we don't need to specify another value for Appointment type. it defaults
// to "Appointment"
}