我在保存记录时得到Invalid column name 'Discriminator'
。 (Code First,EF4.1)
我有一个我希望通过EF跟踪的实体:
public class Audit
public virtual string p1
public virtual string p2
我有一个专业的UserAudit,它没有添加新的虚拟属性,它只是为审计设置了基础
public class UserAudit : Audit
public UserAudit() { p1 = someval; }
配置:
public class AuditConfiguration : EntityTypeConfiguration<Audit>
{
public AuditConfiguration()
{
ToTable("_AUDIT");
HasKey(c => c.Id);
Property(c => c.Id).HasColumnName("AUDIT_ID");
}
}
回购:
public class AuditRepository : IAuditRepository
{
public void LogAudit(Audit audit)
{
using (var db = new AuditContext())
{
db.Audits.Add(audit);
db.SaveChanges();
}
}
}
当我repo.LogAudit( userAudit );
时,我需要做什么来告诉EF正确忽略/处理专业?
答案 0 :(得分:5)
从异常消息Invalid column name 'Discriminator'
我得出结论,你没有让EF 4.1创建数据库表_AUDIT
,否则EF会在表中创建一个名为Discriminator
的列。也许你有一个没有这样一列的现有数据库表。当EF试图保存实体时,它想要存储一个表示您要保存到鉴别器列中的具体类型的值 - 但该列不存在。因此例外。
修改强>
因此,您需要一个鉴别器列。您可以定义自己的自定义鉴别器列,如下所示:
public class AuditConfiguration : EntityTypeConfiguration<Audit>
{
public AuditConfiguration()
{
ToTable("_AUDIT");
HasKey(c => c.Id);
Property(c => c.Id).HasColumnName("AUDIT_ID");
Map<Audit>(m => m.Requires("Type").HasValue<byte>(0).IsRequired());
Map<UserAudit>(m => m.Requires("Type").HasValue<byte>(1).IsRequired());
}
}
这会在tinyint
表中使用不可为空的Type
列_AUDIT
,其值0
用于基本Audit
类型对象和值{{ 1}}用于派生的1
类型对象。
答案 1 :(得分:1)
@Slauma绝对正确,你应该使用他的解决方案。我只是在解释为什么会发生这种情况。
实体中的继承必须在数据库中建模,因为当您从数据库加载实体时,EF必须知道它是否应该实现Audit
或UserAudit
实例。默认情况下,EF使用名为Table per Hierarchy继承的东西,其中基类型和所有子类型存储在同一个表中。为了支持这种情况,EF期望默认的Discriminator调用表中的附加列。此列将用于存储不同的实例 - 默认情况下,它包含类型的名称。
答案 2 :(得分:1)
就我而言,非EF模型继承自EF模型。我已经将所有属性复制到非EF模型而不是继承,这对我来说就是解决方案。
public class ApplicationContext : DbContext
{
public DbSet<Person> Persons { get; set; }
}
public class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
}
<强>之前:强>
public class PersonWithExtraInfo:Person
{
public string ExtraInfo { get; set; }
}
<强>后:强>
public class PersonWithExtraInfo
{
public int PersonId { get; set; }
public string Name { get; set; }
public string ExtraInfo { get; set; }
}