This is a migrated thread and some comments may be shown as answers.

Detach, ObjectScope and InvalidOperationException.

3 Answers 164 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Jose Mejia
Top achievements
Rank 1
Jose Mejia asked on 30 Oct 2012, 06:29 PM
Hello.

Suppose the following code:

MainEntity mainE;
 MainEntity newmainE;
  using (TestBenchModel model = new TestBenchModel())
    {
   mainE = model.MainEntities.SingleOrDefault(t => t.MainId == 10);
     newmainE = model.CreateDetachedCopy(mainE, t=>t.Helper1,t=>t.Properties);
  }
 
 
 
newmainE.Value = new Random().Next().ToString();
 
 using (TestBenchModel model = new TestBenchModel())
 {
    MainEntity mainEntity = new MainEntity { Value = "123456" };
    foreach (var helper1 in newmainE.Helper1)
     {
        mainEntity.Helper1.Add(helper1);
      }
    foreach (var prop in newmainE.Properties)
      {
        mainEntity.Properties.Add(prop);
      }
 
     model.AttachCopy(mainEntity);

I've got the following exception:
Telerik.OpenAccess.Exceptions.InvalidOperationException was unhandled
  Message=Object references between two different object scopes are not allowed. The object 'OAEagerLoadingTest.Helper1' is already managed by 'ObjectScopeImpl 0x2' and was tried to be managed again by 'ObjectScopeImpl 0x4'.


Why I'm getting this execption, because  the state oh Helper1 entities is DetachedClean?
Or newMain.Helper1 values and newMain.Properties are linked only to newMain object (belong to newMain object scope???), so I can't use them with other objects?

Thanks in advance.

3 Answers, 1 is accepted

Sort by
0
Accepted
Thomas
Telerik team
answered on 31 Oct 2012, 02:36 PM
Hi Jose,

you are creating cross-references between the fresh mainEntity instance and the parts of the detached graph from the newmainE instance. During AttachCopy the fresh mainEntity is then transitivly referencing the detached instances, and this is currently not supported.
What you can do is to create a fresh mainEntity with the new Value, Add() that to the context. Then perform the AttachCopy of the newmainE, and set the return value as the mainEntity.Helper1 value. Likewise for the properties. This guarantees us that all references are within one context at the end.

Regards,
Thomas
the Telerik team
Telerik OpenAccess ORM Meets ASP.NET Web API. Read more.
0
Jose Mejia
Top achievements
Rank 1
answered on 31 Oct 2012, 03:57 PM
Hello, Thomas .

Your solution seems to work, but if association property IsManaged = true  on Target  side,
then the following code:

using (TestBenchModel model = new TestBenchModel())
 {
     MainEntity mainEntity = new MainEntity { Value = "123456" };
     model.Add(mainEntity);
               
     newmainE = model.AttachCopy(newmainE);
 
    foreach (var helper1 in newmainE.Helper1)
    {
       mainEntity.Helper1.Add(helper1);
    }

in foreach loop on second iteration throws:

System.InvalidOperationException was unhandled
  Message=Collection was modified; enumeration operation may not execute.

If IsManaged set to false then it seems to work.
Is it bug or it is expected behavior? What if I need to keep IsManaged = true?

Thanks in advance.
0
Accepted
Thomas
Telerik team
answered on 01 Nov 2012, 10:13 AM
Hello Jose,

the IsManaged property tells the foreign-key collection to maintain the inverse reference in the other side; effectively freeing the user from doing that job. So when an OrderDetail is added to the details collection of the Order, the runtime will modify the OrderDetails order reference.
I think this happens regardless of the context the instance is bound to, and in such code as yours, the automatism of this might bite you.
The exception you are getting now is a different one: By logically modifying the collection while enumerating it the enumeration process fails. This happens also for pur CLR collections! You will need to create a copy (.ToList()) before you perform the .Add(helper1).

Regards,
Thomas
the Telerik team
Telerik OpenAccess ORM Meets ASP.NET Web API. Read more.
Tags
General Discussions
Asked by
Jose Mejia
Top achievements
Rank 1
Answers by
Thomas
Telerik team
Jose Mejia
Top achievements
Rank 1
Share this question
or