实体框架中TPH继承的映射配置错误?

时间:2016-10-28 18:09:55

标签: c# entity-framework ef-code-first tph

我尝试在Code First和FluentApi的域上应用TPH继承策略。

我有以下域名模型:

public abstract class Entity
{
    public Guid Id { get; set; }
    public byte [] RowVersion { get; set; }
}

public class Employee : Entity
{
    #region POCO Fields 
    public string EmployeeId { get; set; }
    //Complex Types
    public PrimaryPersonalData PrimaryPersonalData { get; set; } 
    public ContactPersonalData ContactPersonalData { get; set; }

    #endregion

    #region Navigations
    public ICollection<EmployeePosition> EmployeeCurrentPositions { get; set; }
    public ICollection<EmployeeDegree> EmployeeCurrentDegrees { get; set; }
    public ICollection<EmployeeRole> EmployeeCurrentRoles { get; set; }
    public ICollection<Department> AdministrationDepartments { get; set; }

    public Guid? FacultyId { get; set; }
    public Faculty Faculty { get; set; }
    public Guid? SectorId { get; set; }
    public Sector Sector { get; set; }
    public Guid? AcademicDepartmentId { get; set; }
    public Department AcademicDepartment { get; set; }


    #endregion

    #region Constructors
    public Employee()
    {
        EmployeeCurrentPositions = new List<EmployeePosition>();
        EmployeeCurrentDegrees = new List<EmployeeDegree>();
        EmployeeCurrentRoles = new List<EmployeeRole>();
        AdministrationDepartments = new List<Department>();
        PrimaryPersonalData = new PrimaryPersonalData();
        ContactPersonalData = new ContactPersonalData();

    }

    #endregion

}

public class Teacher : Employee
{
    public ICollection<Subject> ReadeableSubjects { get; set; }
    public Teacher()
    {
        ReadeableSubjects = new List<Subject>();
    }
}

配置分开:

public abstract class EntityConfiguration<T> : EntityTypeConfiguration<T>
    where T : Entity
{
    protected EntityConfiguration()
    {
        HasKey(p => p.Id);
        Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        Property(p => p.RowVersion).IsRowVersion();
    }
}

public class EmployeeConfiguration : EntityConfiguration<Employee>
{
    public EmployeeConfiguration()
    {
        #region POCO Configuration
        Property(p=>p.EmployeeId)
            .IsRequired()
            .IsConcurrencyToken(true);

        #endregion

        #region Mapping Configuration
        HasMany(p => p.EmployeeCurrentPositions)
           .WithMany(p => p.TakingEmployees)
           .Map(p =>
           {
               p.MapLeftKey("EmployeeId");
               p.MapRightKey("PositionId");
               p.ToTable("EmployeePosition");
           });

        HasMany(p => p.EmployeeCurrentDegrees)
            .WithMany(p => p.TakingEmployees)
            .Map(p =>
            {
                p.MapLeftKey("EmployeeId");
                p.MapRightKey("DegreeId");
                p.ToTable("EmployeeDegree");
            });

        HasMany(p => p.EmployeeCurrentRoles)
            .WithMany(p => p.TakingEmployees)
            .Map(p =>
            {
                p.MapLeftKey("EmployeeId");
                p.MapRightKey("RoleId");
                p.ToTable("EmployeeRole");
            });

        #endregion

    }

public class TeacherConfiguration : EntityConfiguration<Teacher>
{
    // I suppose problem is hidden here. TeacherConfiguration inherits from 
    // EntityConfiguration and may miss configuration of Employee. Am I right?
    public TeacherConfiguration()
    {
        HasMany(p => p.ReadeableSubjects).WithMany(p => p.ReadeableTeachers).Map(m =>
        {
            m.MapLeftKey("TeacherId");
            m.MapRightKey("SubjectId");
            m.ToTable("TeacherSubject");
        });
    }
}

最后一部分 - 教师班级,包括员工和教师。

public class Faculty : Entity
{
    #region POCO Fields
    public string Acronym { get; set; }
    public string FacultyNameEn { get; set; }
    public string FacultyNameRu { get; set; }
    public string FacultyDescriptionEn { get; set; }
    public string FacultyDescriptionRu { get; set; }

    #endregion

    #region Navigations
    public ICollection<Department> Departments { get; set; }
    public ICollection<Employee> Employees { get; set; }
    public ICollection<Teacher> Teachers { get; set; }
    public ICollection<Student> Students { get; set; }
    public ICollection<Subject> Subjects { get; set; }
    public ICollection<Specialty> Specialties { get; set; }

    #endregion

    #region Constructors

    public Faculty(string facultyAcronym, string facultyNameEn, string facultyNameRu,
        string facultyDescriptionEn, string facultyDescriptionRu)
        : this()
    {
        Acronym = facultyAcronym;
        FacultyNameEn = facultyNameEn;
        FacultyNameRu = facultyNameRu;
        FacultyDescriptionEn = facultyDescriptionEn;
        FacultyDescriptionRu = facultyDescriptionRu;
    }
    public Faculty()
    {
        Departments = new List<Department>();
        Employees = new List<Employee>();
        Students = new List<Student>();
        Subjects = new List<Subject>();
        Specialties = new List<Specialty>();
        Teachers = new List<Teacher>();
    }
    #endregion

}

public class FacultyConfiguration : EntityConfiguration<Faculty>
{
    public FacultyConfiguration()
    {
        #region POCO Configurations
        Property(p => p.Acronym)
            .IsRequired()
            .HasMaxLength(10);

        Property(p => p.FacultyNameEn)
            .IsRequired()
            .HasMaxLength(100);

        Property(p => p.FacultyNameRu)
            .IsRequired()
            .HasMaxLength(100);

        Property(p => p.FacultyDescriptionEn)
            .IsRequired()
            .HasMaxLength(1000);

        Property(p => p.FacultyDescriptionRu)
            .IsRequired()
            .HasMaxLength(1000);

        #endregion

        #region Mapping Configurations
        HasMany(p => p.Departments)
            .WithRequired(p => p.Faculty)
            .HasForeignKey(p => p.FacultyId);

        HasMany(p => p.Employees)
            .WithOptional(p => p.Faculty)
            .HasForeignKey(p => p.FacultyId);

        HasMany(p => p.Teachers)
            .WithOptional(p => p.Faculty)
            .HasForeignKey(p => p.FacultyId);

        HasMany(p => p.Students)
            .WithRequired(p => p.Faculty)
            .HasForeignKey(p => p.FacultyId);

        HasMany(p => p.Subjects)
            .WithRequired(p => p.Faculty)
            .HasForeignKey(p => p.FacultyId);

        HasMany(p => p.Specialties)
            .WithRequired(p => p.Faculty)
            .HasForeignKey(p => p.FacultyId);
        #endregion

    }
}

最后我得到了一个例外:

  

附加信息:外键组件&#39; FacultyId&#39;不是类型&#39;教师&#39;的声明属性。验证它是否未从模型中明确排除,并且它是有效的原始属性。

我发现了类似的问题here,但情况有点不同。我认为问题是TeacherConfiguration继承自EntityConfiguration,但不是来自EmployeeConfiguration。你能帮我找一下这里有什么问题吗?

0 个答案:

没有答案