How to prevent Silverlight RIA Entity from attaching to a datacontext before I'm ready

I have a Silverlight 4 application for a simple "TODO" list. The problem I am facing is that the data binding binds relationships with my TODO object, which causes the RIA data context to add it to the DataContext.TODOs list before I want it there. I want to treat the object as new and disconnected until I explicitly add it to the datacontext.


Here's how it works: I have a TODO object that is associated with a Status (RIA service object relation).

I create a new TODO() object that is passed to the ChildWindow . Please note that I am not adding this new object to my datacontext.

  new CreateTODOPopup(new TODO()).Show(); 

In the DataForm in my ChildWindow, I have a combo box for Status that binds to DataContext.Statuses .

The problem is that the action of selecting Status from the drop-down list actually associates the entity with the context for me - ending up giving it EntityState.New status and actually adding it to the DataContext.TODOs collection.

That would be nice, except that now it appears in the main TODO list in the main frame. I do not want this because it has not yet been captured by ChildWindow.

How can i solve this? Either by hindering the attachment of an object, or by hiding it in some way from any controls, it is tied until it is added.

+4
source share
4 answers

You should be able to get the behavior you want by adding another "MyProject" property to the TODO entity using a partial class. In your pop-up menu, you can set the "MyProject" property instead of the "Project" property. When you save TODO, you can apply the value "MyProject" directly to "Project". A bit of a workaround, but it should give you the behavior you would like.

Kyle

+1
source

I suggest that one way would be to use a PagedCollectionView and filter out the "new" entities - but there should be something obvious missing.

  // data bind list to this ICollectionView private PagedCollectionView _projects; public PagedCollectionView Projects { get { if (_projects == null) { _projects = new PagedCollectionView(_todoDomainContext.TODOProjects) { Filter = i => { DM.TODOProject proj = (DM.TODOProject)i; // hide New entities if (proj.EntityState == EntityState.New) { return false; } return true; } }; } return _projects; } } 
+1
source

IMPORTANT: After 3 days of struggle with a terrible state such as a race, he turned out to be directly related to this problem. Basically the conclusion: if you are trying to create entities and not add them to the data context, then not if you do not want race conditions and unexpected behavior. I am sure this is a RIA service error.

What I did:

  • Creating new TODO() and passing it to my view
  • Allow the RIA services infrastructure to link my TODO to all foreign key tables such as Status and AssignedTo
  • In "Save" add TODO() to the list, if it was not already present in the set of DataContext.TODOs objects.

What the frame did on its own:

  • When the view sets the foreign keys of the object (via comobox), it automatically adds TODO to the DataContext.TODOs collection. This is exactly how entities work.

Why is that bad:

  • When navigating through my user interface, a terrible race condition occurred.
  • Existing lines (even those that existed before the start of my application) were marked as New - sometimes up to 20 of them, and then rewritten as new duplicate lines.

How I fixed it:

  • Always add created objects to the data context directly when creating.

Here is an example code to add objects immediately to creation - there is no race condition:

 for (int i = 0; i < 3; i++) { var entity = new DM.TODO(); _todoDomainContext.TODOs.Add(entity); entity.TODOStatu = pendingStatus; entity.TODOProject = project; entity.TODOCompany = company; entity.CreateDt = DateTime.Now; entity.Title = "generated todo " + DateTime.Now.ToString(); entity.Details = "12345"; } 

This code did NOT work and causes race conditions - adding objects after foreign key restrictions has already been set:

 for (int i = 0; i < 3; i++) { var entity = new DM.TODO(); entity.TODOStatu = pendingStatus; entity.TODOProject = project; entity.TODOCompany = company; entity.CreateDt = DateTime.Now; entity.Title = "generated todo " + DateTime.Now.ToString(); entity.Details = "12345"; _todoDomainContext.TODOs.Add(entity); } 
+1
source

Have you tried using Context.Detach on an object to clearly indicate that it should not be in context? Then you can use Context.Attach before saving it.

0
source

Source: https://habr.com/ru/post/1315606/


All Articles