5

In my ViewModel I have some code like that:

public class OrderViewModel
{
    private UserOrder order;
    private DeliveryCentre deliveryCentre;

    // This is my EF Container
    private CatalogueContainer catalogue = new CatalogueContainer();

    // do some stuff...

    public void Save()
    {
        if (order == null)
        {
            order = catalogue.UserOrders.CreateObject();
        }
        // do some other stuff...

         if ((deliveryCentre == null)
            || (deliveryCentre.Id != deliveryCentreId))
        {
           deliveryCentre = catalogue.DeliveryCentres.First(centre => centre.Id == deliveryCentreId);

            //Causes a context error, not sure why...
            order.DeliveryCentre= deliveryCentre;
        }

        catalogue.SaveChanges();

    }

So when the delivery centre is new and the order is new, I am hit by the old "The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects" error, which seems a trifle unfair to me - I just can't figure out what I need to do to make them belong more to the same object context. I assume this is due to some fundamental misunderstanding of the behaviour of Entity Framework.

glenatron
  • 11,018
  • 13
  • 64
  • 112

2 Answers2

3

You are not disposing your context. It may be possible that one of the entities order or deliveryCentre is attached to an old context which still holds references to the entities. You can create and dispose your context with an using statement inside of the Save method instead to using it as a member variable:

public void Save()
{
    using (var catalogue = new CatalogueContainer())
    {
        // your code...
    }
}

And remove the private catalogue member.

Slauma
  • 175,098
  • 59
  • 401
  • 420
  • Well the order is being created from the context at the start of the method, the deliveryCentre is being queried from it a few lines later. Am I right in understanding from this that a context isn't something that can be safely maintained across the lifetime of an object? Can you suggest any good resources on what the hidden characteristics causing this problem are and how to use the context safely? – glenatron Apr 26 '12 at 13:05
  • @glenatron: `ObjectContext` implements `IDisposable` because there is an unmanaged resource (Db connection) which should be disposed. If you have an entity attached to two different contexts that are not disposed you get the error you are having. I don't see that this problem could occur in your code but there are "...do stuff..." placeholders and I don't know the whole context of your code. Did you test my proposal if it solves the problem? – Slauma Apr 26 '12 at 15:19
  • The "...do stuff..." is just basically validating and assigning order properties - I couldn't see anything much else there but when I comment it out, the error stops occurring, which leads me to wonder if I have another relationship I'm assigning that might be using an expired objectcontext for something and the message arising here is just a bit misleading. – glenatron Apr 27 '12 at 10:03
2

The solution turned out to only be indirectly related to the error message- @Slauma asked about the //do stuff... placeholders and when I commented those out the error disappeared.

It turned out that there was another relationship there, where I was creating the object as this.Item = new Item() rather than using this.Item = catalogue.Items.CreateObject() so it was being created out of context and when it was added to the order, although the order itself was created from the local context, when the Item was added to it this was somehow dirtying up the context but for some reason this only showed up as a problem when I added the next related object.

glenatron
  • 11,018
  • 13
  • 64
  • 112