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.
Did you try removing both of these lines from StudentMap and TeacherMap?
this.HasKey(t => t.PersonId); // Is this need or not???
this.ToTable("Persons"); // Is this need or not???
I copied your code and ran it without these lines and it worked just fine.
I little rewrite your code, it takes what you want:
You have the PersonId as primary key and all other limits are present.
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);
}
}
Your DB looks like:

add code for test
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();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With