几天来,我一直在绞尽脑汁在 Interwebz 上搜索有关如何使用实体框架 (EF) 将数据插入数据库交叉表的信息。我访问了所有主要玩家的网站和博客,但没有人提供关于如何执行此操作的简单语法。出乎意料的是,我想到了答案,我有义务并决心与尽可能多的人分享这个问题,以减轻我所经历的痛苦。
让我们设置舞台。假设我们有这样的数据库关系:
学生 (StudentID(PK)、StudentName、Gender)
课程 (CourseID(PK)、CourseName、CourseDescription)
StudentsCourses (StudentID(PK, FK), CourseID(PK, FK))
对于那些对 EF 足够熟悉的人,您知道当将上述关系转换为实体数据模型时,Students 和 Courses 表被创建为实体,但 StudentsCourses 表不是。这是因为StudentCourses表除了其他两个表的键之外不包含任何属性,所以EF直接映射Students和Courses之间的多对多关系(EF在这方面不受关系数据库的限制.) 而不是实体,而是将交集表转换为 AssociationSet。如果您不知道这种行为,请查看以下链接以获取示例:
http://thedatafarm.com/blog/data-access/inserting-many-to-many-relationships-in-ef-with-or-without-a-join-entity/
http://weblogs.asp.net/ zeeshanhirani/archive/2008/08/21/many-to-many-mappings-in-entity-framework.aspx
现在让我们假设您想为当前学生 (ID:123456) 注册本学期的新课程(ENGL101、SOC102 和 PHY100)。在这种情况下,我们希望使用 Student 表和 Courses 表中的现有信息将新记录插入到 StudentsCourses 表中。使用这些表中的任何一个表中的数据都很容易,因为它们都是模型中的实体,但是您不能直接访问 StudentCourses 表,因为它不是实体。这种困境的关键在于每个实体的导航属性。Student 实体具有到 Course 实体的导航属性,反之亦然。我们将使用这些来创建“关联记录”,我喜欢这样称呼它们。
以下是将现有学生与现有课程相关联的代码示例:
using (var context = TheContext())
{
Student st = context.Students.Where(s => s.StudentID == “123456”).First();
st.Courses.Add(context.Courses.Where(c => c.CourseID == “ENGL101”).First());
st.Courses.Add(context.Courses.Where(c => c.CourseID == “SOC102”).First());
st.Courses.Add(context.Courses.Where(c => c.CourseID == “PHY100”).First());
context.Students.AddObject(st);
context.SaveChanges();
}
因为关联是双向的,所以可以按道理检索三个 Course 对象(通过 CourseID)并将相同的 Student 对象关联到每个对象,但我自己还没有测试过。我认为这会导致代码过多,并且可能在语义上令人困惑。
这是一个将新学生与相同的现有课程相关联的代码示例:
using (var context = TheContext())
{
Student st = new Student({ StudentID = “654321”, StudentName = “Rudolph Reindeer”,
Gender = “Male” });
st.Courses.Add(context.Courses.Where(c => c.CourseID == “ENGL101”).First());
st.Courses.Add(context.Courses.Where(c => c.CourseID == “SOC102”).First());
st.Courses.Add(context.Courses.Where(c => c.CourseID == “PHY100”).First());
context.Students.AddObject(st);
context.SaveChanges();
}
最后,这是将新学生与新课程相关联的代码('...' 用于简洁):
using (var context = TheContext())
{
Student st = new Student({ ... });
st.Courses.Add(new Course({ ... }));
st.Courses.Add(new Course({ ... }));
st.Courses.Add(new Course({ ... }));
context.Students.AddObject(st);
context.SaveChanges();
}