Code First 的 EF 4.1 中的 TPH 继承映射问题
我的 ASP.NET MVC 应用程序中有这些类:
public abstract class Person {
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Student : Person {
public DateTime RegisteredOnUtc { get; set; }
public int Age { get; set; }
}
public class Teacher : Person {
public string LessonName { get; set; }
}
public class PersonMap : EntityTypeConfiguration<Person> {
public PersonMap()
: base() {
this.HasKey(t => t.PersonId);
this.Property(t => t.FirstName)
.IsRequired()
.HasMaxLength(50);
this.Property(t => t.LastName)
.IsRequired()
.HasMaxLength(50);
this.ToTable("Persons");
this.Property(t => t.PersonId).HasColumnName("PersonId");
this.Property(t => t.FirstName).HasColumnName("FirstName");
this.Property(t => t.LastName).HasColumnName("LastName");
this.Map<Student>(x => x.Requires("IsStudent").HasValue(true));
this.Map<Teacher>(x => x.Requires("IsStudent").HasValue(false));
}
}
public class StudentMap : EntityTypeConfiguration<Student> {
public StudentMap()
: base() {
this.HasKey(t => t.PersonId); // Is this need or not???
this.ToTable("Persons"); // Is this need or not???
this.Property(t => t.RegisteredOnUtc).HasColumnName("RegisteredOn");
}
}
public class TeacherMap : EntityTypeConfiguration<Teacher> {
public TeacherMap()
: base() {
this.HasKey(t => t.PersonId); // Is this need or not???
this.ToTable("Persons"); // Is this need or not???
this.Property(t => t.LessonName)
.IsRequired()
.HasMaxLength(50);
this.Property(t => t.LessonName).HasColumnName("Lesson");
}
}
public class PersonContext : DbContext {
public ObjectContext ObjectContext {
get {
return ((IObjectContextAdapter)this).ObjectContext;
}
}
public DbSet<Person> Persons { get; set; }
public DbSet<Student> Students { get; set; }
public DbSet<Teacher> Teachers { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
modelBuilder.Configurations.Add(new PersonMap());
modelBuilder.Configurations.Add(new StudentMap());
modelBuilder.Configurations.Add(new TeacherMap());
}
public void Detach(object entity) {
var objectContext = ((IObjectContextAdapter)this).ObjectContext;
objectContext.Detach(entity);
}
}
但是,当我运行应用程序时,出现此错误:
属性 'PersonId'
不是类型 < 上声明的属性代码>“学生”。使用 Ignore
方法或 NotMappedAttribute
数据注释验证该属性是否未从模型中显式排除。确保它是一个有效的原始属性。
如果删除 this.HasKey(t => t.PersonId);
Student
和 Teacher
,将抛出此错误:
字典中不存在给定的键。
你有吗有什么想法可以解决这个问题吗?谢谢。
I have these classes in my ASP.NET MVC app:
public abstract class Person {
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Student : Person {
public DateTime RegisteredOnUtc { get; set; }
public int Age { get; set; }
}
public class Teacher : Person {
public string LessonName { get; set; }
}
public class PersonMap : EntityTypeConfiguration<Person> {
public PersonMap()
: base() {
this.HasKey(t => t.PersonId);
this.Property(t => t.FirstName)
.IsRequired()
.HasMaxLength(50);
this.Property(t => t.LastName)
.IsRequired()
.HasMaxLength(50);
this.ToTable("Persons");
this.Property(t => t.PersonId).HasColumnName("PersonId");
this.Property(t => t.FirstName).HasColumnName("FirstName");
this.Property(t => t.LastName).HasColumnName("LastName");
this.Map<Student>(x => x.Requires("IsStudent").HasValue(true));
this.Map<Teacher>(x => x.Requires("IsStudent").HasValue(false));
}
}
public class StudentMap : EntityTypeConfiguration<Student> {
public StudentMap()
: base() {
this.HasKey(t => t.PersonId); // Is this need or not???
this.ToTable("Persons"); // Is this need or not???
this.Property(t => t.RegisteredOnUtc).HasColumnName("RegisteredOn");
}
}
public class TeacherMap : EntityTypeConfiguration<Teacher> {
public TeacherMap()
: base() {
this.HasKey(t => t.PersonId); // Is this need or not???
this.ToTable("Persons"); // Is this need or not???
this.Property(t => t.LessonName)
.IsRequired()
.HasMaxLength(50);
this.Property(t => t.LessonName).HasColumnName("Lesson");
}
}
public class PersonContext : DbContext {
public ObjectContext ObjectContext {
get {
return ((IObjectContextAdapter)this).ObjectContext;
}
}
public DbSet<Person> Persons { get; set; }
public DbSet<Student> Students { get; set; }
public DbSet<Teacher> Teachers { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
modelBuilder.Configurations.Add(new PersonMap());
modelBuilder.Configurations.Add(new StudentMap());
modelBuilder.Configurations.Add(new TeacherMap());
}
public void Detach(object entity) {
var objectContext = ((IObjectContextAdapter)this).ObjectContext;
objectContext.Detach(entity);
}
}
But, when I run the app, get this error:
The property 'PersonId'
is not a declared property on type 'Student'
. Verify that the property has not been explicitly excluded from the model by using the Ignore
method or NotMappedAttribute
data annotation. Make sure that it is a valid primitive property.
And if remove this.HasKey(t => t.PersonId);
from the Student
and Teacher
, this error will be thrown:
The given key was not present in the dictionary.
Have you any idea to resolve this please? Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您是否尝试从 StudentMap 和 TeacherMap 中删除这两行?
我复制了你的代码并在没有这些行的情况下运行它,它工作得很好。
Did you try removing both of these lines from StudentMap and TeacherMap?
I copied your code and ran it without these lines and it worked just fine.
我很少重写你的代码,它需要你想要的:
你有 PersonId 作为主键
并且存在所有其他限制。
您的数据库如下所示:
添加测试代码
I little rewrite your code, it takes what you want:
You have the PersonId as primary key
and all other limits are present.
Your DB looks like:
add code for test
如果您将 Students 和 Teachers 包含在 PersonContext 类中,我认为这不是 TPH 继承。 TPH 的全部意义不就是只有一张表(Person 表)吗? 我会删除这两行
如果您查看 本演练,特别是“将人员实体类型添加到模型”部分,您会明白我的意思。我不确定这是否与您的特定问题有很大关系,但无论如何您可能需要注意它。
I don't think it's TPH inheritance if you include the Students and Teachers in the PersonContext class. Isn't the whole point of TPH to just have one table, the Person table? I'd remove these two lines
If you look at this walkthrough, particularly the 'Adding the Person Entity Type to the Model' section you'll see what I mean. I'm not sure if this has much to do with your particular problem but you might want to note it anyway.