我有以下数据结构:
class Person
{
public int PersonId {get; set}
public string Name {get; set;}
public string FieldWithUniqueConstraint {get; set}
}
class Student : Person
{
public string StudentNumber {get; set;}
}
class Teacher : Person
{
public string EmployeeNumber {get; set;}
}
我在EF6中使用TPT Hierarchy,因此上述实体在SQL Server中作为3个表存在。
创建新的学生和教师工作正常,但现在教师也需要成为学生。
如果我使用现有的PersonId在数据库中手动创建学生子类型的新记录,则SQL Server不会提出任何投诉。我使用db.Students/Teachers.SingleOrDefault(e => e.PersonId == personId);
但是,我究竟如何使用现有的教师来创建新学生?由于主要密钥违规,简单地执行db.Students.Add()
不起作用,我理解为什么。
如果我设法创建了一个,你将如何删除一种类型?
诀窍在于,属性FieldWithUniqueContraint
必须存在于结构中,否则解决方案很简单,只需创建另一条记录,但Person记录必须由两个子类型共享。
对此问题的任何见解都将不胜感激。
答案 0 :(得分:0)
'正确'我解决这个问题的方法是将我的结构简化为一个表(类似于TPH,但没有鉴别器),并在问题的评论中为@GertArnold分配角色(见下文):
class Person
{
public int PersonId {get; set}
public string Name {get; set;}
public string StudentNumber {get; set;}
public string FieldWithUniqueConstraint {get; set}
public string EmployeeNumber {get; set;}
public virtual ICollection<PersonRole> PersonRoles {get; set}
}
class PersonRole
{
public in PersonRoleId {get; set;}
public ICollection<Person> People {get; set;}
public string RoleName {get; set;}
}
但是由于时间限制和需要从多个表合并为一个的实时数据,我不得不接受一个快速而肮脏的解决方案。在我们的场景中,学生/教师也需要成为教师/学生,这种情况很少见(1万分之一),所以我们最终手动“完成了”。在所需的子类型中创建记录:
db.Database.ExecuteSqlCommand("INSERT INTO Learner (PersonId, StudentNumber) VALUES (@PersonId, @StudentNumber)",
new SqlParameter("@PersonId", id),
new SqlParameter("@StudentNumber", "The Student's Number"));
感觉有点像一个&#39; hack&#39;对我来说,但现在,这就足够了。欢迎评论。