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

感謝您的留言 –