3

我有这些类在我的ASP.NET MVC应用程序:问题与EF 4.1 TPH继承映射与代码首先

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'不是'Student'类型的声明属性。通过使用Ignore方法或NotMappedAttribute数据注释验证该属性是否未明确从模型中排除。确保它是一个有效的基本属性。

如果从StudentTeacher删除this.HasKey(t => t.PersonId);,这个错误将被抛出:

给定的关键是不存在的字典。

您有任何想法解决此问题吗?谢谢。

+0

也许这是服务器的问题。尝试将代码粘贴到简单的控制台应用程序并进行测试。我发布了我如何做到这一点的例子。 –

回答

1

我有点重写代码,它把你想要的东西:

你有PERSONID作为主键 和其他所有的限制都存在。

public abstract class Person 
{ 
    public int PersonId { get; set; } 

    [Required] 
    [MaxLength(50)] 
    public string FirstName { get; set; } 

    [Required] 
    [MaxLength(50)] 
    public string LastName { get; set; } 
} 

public class Student : Person 
{ 
    [Column("RegisteredOn")] 
    public DateTime RegisteredOnUtc { get; set; } 
    public int Age { get; set; } 
} 

public class Teacher : Person 
{ 
    [Required] 
    [MaxLength(50)] 
    public string LessonName { get; set; } 
} 

public class PersonMap : EntityTypeConfiguration<Person> 
{ 
    public PersonMap() 
    { 
     Map<Student>(x => x.Requires("IsStudent").HasValue(true)); 
     Map<Teacher>(x => x.Requires("IsStudent").HasValue(false)); 
    } 
} 

public class PersonContext : DbContext 
{ 
    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()); 
    } 

    public void Detach(object entity) 
    { 
     var objectContext = ((IObjectContextAdapter)this).ObjectContext; 
     objectContext.Detach(entity); 
    } 
} 

你的DB的样子:

enter image description here

插件代码测试

using System; 
    using System.Data.Entity; 
    using System.Data.Entity.Infrastructure; 
    using System.Data.Entity.ModelConfiguration; 
    using System.Data.Objects; 

    namespace ConsoleApplication5 
    { 
     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.Property(t => t.RegisteredOnUtc).HasColumnName("RegisteredOn"); 
      } 
     } 

     public class TeacherMap : EntityTypeConfiguration<Teacher> 
     { 
      public TeacherMap() 
       : base() 
      { 

       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); 
      } 
     } 

     public class Program 
     { 
      static void Main() 
      { 
       var personContext = new PersonContext(); 
       personContext.Database.Delete(); 
       personContext.Database.Create(); 
      } 
     } 
    } 
+0

我在我的问题中写道,我测试的应用程序有和没有这条线,你正在谈论。没有差异,不起作用。此外,我现在用这种方式,但在这种情况下,我无法使用它。谢谢 –

+0

我删除所有代码并重新创建它们,问题解决!我永远不知道问题在哪里!你的代码(和@John Allers也是)之前测试过的代码(和解决方案),但没有奏效!我无法理解。所以感谢你的帮助。问候。 –

1

你尝试都来自StudentMap和TeacherMap这些行取出?

this.HasKey(t => t.PersonId); // Is this need or not??? 

this.ToTable("Persons"); // Is this need or not??? 

我复制了你的代码,并运行它没有这些行,它工作得很好。

+0

是的,我做到了,但仍然无法工作 –

+0

当您删除这些行时,您可以发布异常的堆栈跟踪吗? –

+0

我认为mu错误是在另一个地方。该代码(以上)是完整代码的一部分。我认为,我必须删除所有代码,并逐步追踪。感谢您的帮助。问候。 –

1

如果在PersonContext类中包含学生和教师,我不认为它是TPH继承。 TPH的全部重点不仅仅是一张桌子,Person桌子?我想删除这两条线

public DbSet<Student> Students { get; set; } 
public DbSet<Teacher> Teachers { get; set; } 

如果你看一下this walkthrough,特别是“添加的人实体类型示范”部分,你会明白我的意思。我不确定这是否与您的特定问题有很大关系,但您仍可能想要记下它。

+0

感谢您的留言 –