实体框架中有多对多关系的问题

时间:2009-06-08 20:56:33

标签: entity-framework many-to-many entity

我有3个实体 -方向 -市 -GeoPosition

每个方向都有一个地理位置,每个城市都有一组地理位置(这代表一个多边形)

我有5张桌子 - 方向 -cities -geopositions -directionsgeopositions -citiesgeopositions

和EF实体就是这个

alt text http://img192.imageshack.us/img192/5863/entitydesignerdiagram.png

每个实体都有插入,更新和删除的功能导入

我有这个错误

Error 2027: If an EntitySet or AssociationSet includes a function mapping, 
all related entity and AssociationSets in the EntityContainer must also define
 function mappings. The following sets require function mappings: CitiesGeopositions, DepartmentsGeopositions.  

我需要关系表的函数导入??

问题是什么?

2 个答案:

答案 0 :(得分:3)

你的问题的答案分别是:

  1. 见(1)。
  2. 实体框架允许您通过DML或存储过程插入/更新/删除,但它不允许您选择“两者”。如果要转到存储过程路由,则必须为框架可能需要对实体执行的每种数据修改提供过程,包括关系表。

答案 1 :(得分:1)

现在几天,我一直在绞尽脑汁并搜索Interwebz,以获取有关如何使用实体框架(EF)将数据插入数据库交集表的信息。我已经点击了所有主要玩家的网站和博客,NO ONE提供了关于如何执行此操作的直接语法。出乎意料的是,答案发生在我身上,我受到约束并决心与尽可能多的人分享这一点,以减轻我经历的痛苦。

让我们踏上舞台。假设我们有这样的数据库关系:

  

学生(学生ID(PK),学生姓名,性别)
  课程(CourseID(PK),CourseName,CourseDescription)
  学生课程(学生ID(PK,FK),CourseID(PK,FK))

对于那些熟悉EF的人,您知道当上述关系被转换为实体数据模型时,Student和Courses表被创建为实体,但StudentsCourses表不是。这是因为StudentsCourses表不包含除其他两个表中的键之外的任何属性,因此EF直接映射学生和课程之间的多对多关系(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

现在让我们假设你想为本学期的新课程(ENGL101,SOC102和PHY100)注册一名当前学生(ID:123456)。在这种情况下,我们希望使用Students表和Courses表中的现有信息将新记录插入StudentsCourses表。使用来自这两个表中的数据很容易,因为它们都是模型中的实体,但是您不能直接访问StudentsCourses表,因为它不是实体。这种困境的关键在于每个实体的导航属性。 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();
}