我尝试使用 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
}
}
最后我得到了一个例外:
附加信息:外键组件“FacultyId”不是“教师”类型的声明属性。验证它没有被明确地从模型中排除,并且它是一个有效的原始属性。
我在这里发现了类似的问题,但情况有些不同。我认为问题是 TeacherConfiguration 继承自 EntityConfiguration 而不是 EmployeeConfiguration。你能帮我找出这里有什么问题吗?