New Posts New Posts RSS Feed: Is there a multiple entity manager demo?
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Is there a multiple entity manager demo?

 Post Reply Post Reply
Author
hueha View Drop Down
Newbie
Newbie


Joined: 23-Jul-2010
Posts: 38
Post Options Post Options   Quote hueha Quote  Post ReplyReply Direct Link To This Post Topic: Is there a multiple entity manager demo?
    Posted: 11-Sep-2010 at 12:39pm
Is there a demo that shows how to implement multiple entity managers?

I am really struggling to get the multiple entity manager working.  I've been working off the code posted at http://drc.ideablade.com/xwiki/bin/view/Documentation/SavingBusinessObjects#HDependencyGraphRetrieval

However, I'm not sure how to implement the step that says 
"After save, the application might export the saved rep back into the main EM where it now displays in the grid in its post-save glory12."

It seems when I call SaveChangesAsync on the second entity model it is not being committed to the database.  So I basically used the dependency graph retrieval in reverse to get the models back into the main EM.  Some issues I have found are

1) The dependency graph is not picking up items which are still being loaded asynchronously
3) Doesn't like many to many relationships.   I get this error when trying to save
{EntityManagerSaveException: The object being attached to the source object is not attached to the same ObjectContext as the source object. ---> System.InvalidOperationException: The object being attached to the source object is not attached to the same ObjectContext as the source object.
   at System.Data.Objects.DataClasses.RelatedEnd.ValidateEntityForAttach(IEntityWrapper wrappedEntity, Int32 index, Boolean allowCollection)
   at System.Data.Objects.DataClasses.RelatedEnd.Attach(IEnumerable`1 wrappedEntities, Boolean allowCollection)
   at System.Data.Objects.DataClasses.RelatedEnd.System.Data.Objects.DataClasses.IRelatedEnd.Attach(Object entity)
   at IdeaBlade.EntityModel.Edm.EdmSaveHelper.ProcessManyToMany(List`1 entities)
   at IdeaBlade.EntityModel.Edm.EdmSaveHelper.ProcessSaves(IEnumerable`1 groupsByType)
   at IdeaBlade.EntityModel.Edm.EdmSaveHelper.SaveWithinContext()
   at IdeaBlade.EntityModel.Edm.EdmSaveHelper.Save()
   at IdeaBlade.EntityModel.EntityManager.HandleEntityServerException(Exception pException, Boolean pTryToHandle, PersistenceOperation pOperation)
   at IdeaBlade.EntityModel.EntityManager.HandleSaveResultException(SaveWorkState saveWorkState, Boolean isAsyncOp)}
    [IdeaBlade.EntityModel.EntityManagerSaveException]: {EntityManagerSaveException: The object being attached to the source object is not attached to the same ObjectContext as the source object. ---> System.InvalidOperationException: The object being attached to the source object is not attached to the same ObjectContext as the source object.
   at System.Data.Objects.DataClasses.RelatedEnd.ValidateEntityForAttach(IEntityWrapper wrappedEntity, Int32 index, Boolean allowCollection)
   at System.Data.Objects.DataClasses.RelatedEnd.Attach(IEnumerable`1 wrappedEntities, Boolean allowCollection)
   at System.Data.Objects.DataClasses.RelatedEnd.System.Data.Objects.DataClasses.IRelatedEnd.Attach(Object entity)
   at IdeaBlade.EntityModel.Edm.EdmSaveHelper.ProcessManyToMany(List`1 entities)
   at IdeaBlade.EntityModel.Edm.EdmSaveHelper.ProcessSaves(IEnumerable`1 groupsByType)
   at IdeaBlade.EntityModel.Edm.EdmSaveHelper.SaveWithinContext()
   at IdeaBlade.EntityModel.Edm.EdmSaveHelper.Save()
   at IdeaBlade.EntityModel.EntityManager.HandleEntityServerException(Exception pException, Boolean pTryToHandle, PersistenceOperation pOperation)
   at IdeaBlade.EntityModel.EntityManager.HandleSaveResultException(SaveWorkState saveWorkState, Boolean isAsyncOp)}
    Data: {System.Collections.ListDictionaryInternal}
    InnerException: null
    Message: "The object being attached to the source object is not attached to the same ObjectContext as the source object."
    StackTrace: "   at IdeaBlade.EntityModel.EntityManager.HandleEntityServerException(Exception pException, Boolean pTryToHandle, PersistenceOperation pOperation)\r\n   at IdeaBlade.EntityModel.EntityManager.HandleSaveResultException(SaveWorkState saveWorkState, Boolean isAsyncOp)"


Back to Top
sbelini View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 13-Aug-2010
Location: Oakland
Posts: 786
Post Options Post Options   Quote sbelini Quote  Post ReplyReply Direct Link To This Post Posted: 20-Sep-2010 at 6:10pm
Hi,
 
you asked:
However, I'm not sure how to implement the step that says 
"After save, the application might export the saved rep back into the main EM where it now displays in the grid in its post-save glory12."
Basically you will import the graph back to the main EM.
 
It seems when I call SaveChangesAsync on the second entity model it is not being committed to the database.
Are you checking the datasource after the SaveChangesAsync is completed? It won't show on the datasource until it completes.
 
1) The dependency graph is not picking up items which are still being loaded asynchronously
same as above. The asynchronous operation must be completed.
 
3) Doesn't like many to many relationships...
Based on the error message, it seems you are "crossing" entities between more than one entity manager. An entity can only belong to one entity manager. (when you import into a second entity manager, you actually have 2 copies of the same entity) Can you provide a test case reproducing this issue?
 
Below is a simple example (based on the example at http://drc.ideablade.com/xwiki/bin/view/Documentation/SavingBusinessObjects#HDependencyGraphRetrieval) using multiple entity managers using async operations.
 
private void MainPage_Loaded(object sender, RoutedEventArgs e) {
  NorthwindIBEntities em1 = new NorthwindIBEntities();
  NorthwindIBEntities em2 = new NorthwindIBEntities();
  int employeeID = 1;
  var targetedEmployeesQuery = em1.Employees
    .Where(emp => emp.EmployeeID == employeeID)
    .Include("Orders.OrderDetails.Product");
 
  var queryAsync = em1.ExecuteQueryAsync(targetedEmployeesQuery);
 
  queryAsync.Completed += (q, queryArgs) => {
    List<Employee> employees = new List<Employee>(queryArgs.Results);
    Employee anEmployee = employees[0];
    // Create roots list and add the employee.
    List<Entity> roots = new List<Entity>();
    em2.ImportEntities(new Entity[] { anEmployee }, MergeStrategy.OverwriteChanges);
    //edit data on _em2
    var myEditableEmployee = em2.Employees.With(QueryStrategy.CacheOnly).First();
    myEditableEmployee.FirstName = ModifyString(myEditableEmployee.FirstName);
    var op2 = em2.SaveChangesAsync();
    op2.Completed += (s, savedArgs) => {
      em1.ImportEntities(savedArgs.Entities, MergeStrategy.OverwriteChanges);
      //checking if saved items successfully imported back to _em1
      var myEmployeeBackToEM1 = em1.Employees.With(QueryStrategy.CacheOnly).First();
    };
  };
}
 
private String ModifyString(String temp) {
  if (String.IsNullOrEmpty(temp)) {
    return "X";
  } else if (temp.EndsWith("X")) {
    return temp.Substring(0, temp.Length - 1);
  } else {
    return temp + "X";
  }
}
 
Back to Top
cjohnson84 View Drop Down
Groupie
Groupie


Joined: 24-Sep-2009
Location: Akron, Ohio
Posts: 44
Post Options Post Options   Quote cjohnson84 Quote  Post ReplyReply Direct Link To This Post Posted: 06-Oct-2010 at 7:27am
I've been playing with the concepts demonstrated in the sample code above and while this code works well in the case of modified Employee entities or even newly added Employee entities, how do you handle the case where you have deleted an entity in em2?
 
In this case, the SaveChangesAsync call returns saveArgs.Entities containing a "Detached" entity.  When you import the detached entity into em1 with the following line:
 
em1.ImportEntities(savedArgs.Entities, MergeStrategy.OverwriteChanges);
 
Nothing happens...em1 is not "synced".  I was hoping the entity that was deleted in em2 would be removed from em1.
 
How do you handle this scenario or is my thinking wrong here?
Back to Top
sbelini View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 13-Aug-2010
Location: Oakland
Posts: 786
Post Options Post Options   Quote sbelini Quote  Post ReplyReply Direct Link To This Post Posted: 07-Oct-2010 at 10:57am
A Detached entity is not part of any entity manager therefore cannot be imported into another entity manager.
 
A way to handle this sitation is to keep track of the entities that have been deleted (i.e. save callback or SaveResult) on one entity manager and remove then from the other entity managers. ( .RemoveEntity or .RemoveEntities )
Back to Top
cjohnson84 View Drop Down
Groupie
Groupie


Joined: 24-Sep-2009
Location: Akron, Ohio
Posts: 44
Post Options Post Options   Quote cjohnson84 Quote  Post ReplyReply Direct Link To This Post Posted: 07-Oct-2010 at 11:02am
Thank you Silvio for the feedback!  I'll give your suggestion a try.
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down