EF 6 Code First从Supetype创建新的子类型

时间:2018-02-21 12:40:09

标签: c# entity-framework

我有以下数据结构:

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记录必须由两个子类型共享。

对此问题的任何见解都将不胜感激。

1 个答案:

答案 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;对我来说,但现在,这就足够了。欢迎评论。