是否有可能在两个DbContext之间共享POCO对象?

时间:2012-09-14 14:45:37

标签: c# poco dbcontext entity-framework-5

我有一些POCO课程,一般可分为两组,例如:

public class Student
{
    public Student()
    {
        this.Courses = new List<Course>();
        this.Clubs = new List<Club>();
    }

    public int Id { get; set; }
    public virtual ICollection<Course> Courses { get; set; }
    public virtual ICollection<Club> Clubs { get; set; }
}

以及相应的课程和俱乐部课程,他们都与其他课程有自己的关系。

问题是,这两个群体都很大,他们都包含很多课程,而且他们每个人都是一个工作单位,就像学生课程管理单位一样,它将提供与课程相关的任何功能;和俱乐部管理单位将提供功能。所以我不打算将它们放在一个DbContext中。

有一些要求需要从俱乐部获取学生然后检索其课程信息。我现在正在做的是,在课程单元中使用我从俱乐部单元获得的学生ID进行另一个查询。哪个工作正常,但我跳得更简单,就像

foreach(var student in club.Students){
    ClubContext.Detach(student);
    CourseContext.Attach(student);
    foreach(var c in student.Courses){
      ...
    }
}

但我得到了一些例外:

  

已经为对象图层类型生成了代理类型      'POCOTest.Models.Student'。这发生在同一个对象层时      type由AppDomain中的两个或多个不同模型映射。

这可能吗?如果是的话,怎么样?感谢〜

2 个答案:

答案 0 :(得分:2)

您可以在多个上下文中映射单个类,但映射应始终相同。如果它不相同,则无法使用动态代理(延迟加载),因为每个映射都需要自己的代理类型来处理其导航属性。

在您的情况下,第一个上下文映射包含与Student相关的Club实体,但在与Course存在相反关系的第二个映射中不存在此关系。这需要两种不同的代理类型用于相同的实体类型。

例外情况表明它不受支持。有两个原因可以解决这个问题:

  • EF将代理类型存储在静态字典中,其中每个实体类型只能有单个生成的代理
  • 即使你修复了第一点(通过下载源代码并修改它们),你仍然无法做到你想要的,因为代理类型就是实体。它不是一个包装器。因此,当您从第一个上下文中分离并附加到第二个上下文时,该类型无法替换。

答案 1 :(得分:0)

如果您不需要延迟加载,只需删除&#34;虚拟&#34;您的导航属性中的关键字,它将按您的意愿工作。 Virtual用于启用延迟加载。