如何使用实体框架关联来自多个上下文的对象

时间:2020-03-06 14:59:26  来源:igfitidea点击:

我对实体框架还很陌生,所以请多多包涵...

如何将来自不同上下文的两个对象关联在一起?

下面的示例引发以下异常:

System.InvalidOperationException: The
  relationship between the two objects
  cannot be defined because they are
  attached to different ObjectContext
  objects.
void MyFunction()
{
    using (TCPSEntities model = new TCPSEntities())
    {
        EmployeeRoles er = model.EmployeeRoles.First(p=>p.EmployeeId == 123);
        er.Roles = GetDefaultRole();
        model.SaveChanges();
     }
}

private static Roles GetDefaultRole()
{
    Roles r = null;
    using (TCPSEntities model = new TCPSEntities())
    {
        r = model.Roles.First(p => p.RoleId == 1);
    }
    return r;
}

不能选择使用一个上下文,因为我们在ASP.NET应用程序中使用EF。

解决方案

我们将必须使用相同的上下文(可以将上下文传递给getdefaultrole方法)或者重新考虑关系并扩展实体。

编辑:想要为提供的示例添加此内容,使用asp.net将要求我们充分考虑自己的上下文和关系设计。

我们可以简单地传递上下文。IE:

void MyFunction()
{
    using (TCPSEntities model = new TCPSEntities())
    {
        EmployeeRoles er = model.EmployeeRoles.First(p=>p.EmployeeId == 123);
        er.Roles = GetDefaultRole(model);
        model.SaveChanges();
     }

}

private static Roles GetDefaultRole(TCPSEntities model)
{
    Roles r = null;
    r = model.Roles.First(p => p.RoleId == 1);
    return r;
}

在Entity Framework的V1中不支持跨2个或者更多上下文工作。

万一我们还没有找到它,可以在http://blogs.msdn.com/dsimmons/pages/entity-framework-faq.aspx上找到关于EF的常见问题解答

据我了解,我们想尽可能少地实例化模型(通过" new XXXXEntities()"位)。根据MS(http://msdn.microsoft.com/zh-cn/library/cc853327.aspx),这对性能造成了相当大的影响。因此,将其包装在using()结构中并不是一个好主意。我在项目中所做的工作是通过始终提供相同上下文实例的静态方法进行访问:

private static PledgeManagerEntities pledgesEntities;
    public static PledgeManagerEntities PledgeManagerEntities
    {
        get 
        {
            if (pledgesEntities == null)
            {
                pledgesEntities = new PledgeManagerEntities();
            }
            return pledgesEntities; 
        }
        set { pledgesEntities = value; }
    }

然后我像这样检索它:

private PledgeManagerEntities entities = Data.PledgeManagerEntities;

我们可以在此处使用的另一种方法是从一个上下文分离对象,然后将它们添加到另一个上下文。这有点骇人听闻,但在我们遇到的情况下可能无法正常工作,但这可能是一个选择。

public void GuestUserTest()
    {
        SlideLincEntities ctx1 = new SlideLincEntities();
        GuestUser user = GuestUser.CreateGuestUser();
        user.UserName = "Something";
        ctx1.AddToUser(user);
        ctx1.SaveChanges();

        SlideLincEntities ctx2 = new SlideLincEntities();
        ctx1.Detach(user);
        user.UserName = "Something Else";
        ctx2.Attach(user);
        ctx2.SaveChanges();
    }