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' は、タイプ 'Teacher' で宣言されたプロパティではありません。モデルから明示的に除外されていないこと、および有効なプリミティブ プロパティであることを確認してください。
ここで同様の質問を見つけましたが、少し異なる状況があります。問題は、TeacherConfiguration が EntityConfiguration から継承されているが、EmployeeConfiguration から継承されていないことだと思います。ここで何が問題なのかを見つけるのを手伝ってもらえますか?