views:

4932

answers:

6

I am very new to the entity framework, so please bear with me...

How can I relate two objects from different contexts together?

The example below throws the following exception:

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;
    }

Using one context is not an option because we are using the EF in an ASP.NET application.

+3  A: 

You will have to use the same context (you can pass the context to the getdefaultrole method) or rethink the relationships and extend the entity.

EDIT: Wanted to add this was for the example provided, using asp.net will require you to fully think out your context and relationship designs.

You could simply pass the context.. 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;
}
Quintin Robinson
+1  A: 

Yep - working across 2 or more contexts is not supported in V1 of Entity Framework.

Just in case you haven't already found it, there is a good faq on EF at http://blogs.msdn.com/dsimmons/pages/entity-framework-faq.aspx

Eric Nelson
+1  A: 

From what I understand, you want to instantiate your model (via the "new XXXXEntities()" bit) as rarely as possible. According to MS (http://msdn.microsoft.com/en-us/library/cc853327.aspx), that's a pretty substantial performance hit. So wrapping it in a using() structure isn't a good idea. What I've done in my projects is to access it through a static method that always provides the same instance of the context:

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

And then I retrieve it like so:

 private PledgeManagerEntities entities = Data.PledgeManagerEntities;
Ken Smith
A: 

Is this working in as.net context as well?

+1  A: 

Another approach that you could use here is to detach objects from one context, and then attach them to another context. That's a bit of a hack, and it may not work in your situation, but it might be an option.

    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();
    }
Ken Smith