This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
I have a form which has a unitofwork as part of its base class, i.e. a new UOW is created for a static LightSpeedContext when the form is initialised, and then calls SaveChanges when the user is done with the form. So far working reasonably well...
The issue I have is when the user wants to make some extra persistant changes midway through using the form, in this case changes to a "template" - I will whip up an example below
private MyObject thing;
void copyThing(source, target, unitofwork)
are you able to tell me why the second unitofwork's savechanges method is persisting an object which i have not attached to it, and how I would go about making the second UOW only persist the objects which i have explicitly attached to it. |
|
|
Hi Solarflare, Thanks for your detailed post! I'm guessing that your two objects are connected by some type of relationship? When you attach an object to the UoW it will also attach any dependent entities that are currently in memory. This means you're getting the other object attached also which means you'll be saving the changes for that loaded graph. The is a .Detach() method on the UoW which you could pass in the entity you do not wish to persist. This was added in a recent nightly build so you'll need to ensure you're using one of them (if you are not and you upgrade please make sure you uninstall LightSpeed BEFORE installing the nightly). That should give you the granular control you need. Alternatively, when you're working with the objects don't walk the relationship to make sure you don't bring it into the object graph. This will prevent it automatically being saved with the template however it could be a little more fiddly. Let me know if that helps, John-Daniel Trask |
|
|
Thanks, I will grab the latest nightly and try the Detach method. The two objects are of the same type and there is no relationship between them, however they do both use the same entities in their child collections - this is what I tried to address by making the new UoW fetch the child entities by ID, hoping that this would avoid the cached entities on the forms Uow and ensure that all childtren were fetched by the new UoW and therefore completely isolated...
hmm just installed the 29/09 nightly and there is no detach method on a ouw? |
|
|
Detach is on the UnitOfWork class, but is not on the IUnitOfWork interface. You may need to use a strong-typed unit of work, or cast the IUnitOfWork to UnitOfWork. |
|
|
ok I have figured this out, I was forgetting to get the new UoW to fetch a couple of the Entity properties so there were a couple of objects that both parent objects had references to, i.e. it walks every single relationship in the object graph and attaches all entities to the UoW. Now that I understand it I can get around it, even though it means hitting the database again under the new UoW for every single object that the two parent objects have in common in order to build up the object graph so it can be saved.
Can I do this?... instead of void (source, target, newUoW) could i use void (source, target) it is safe to change the childId properties? what happens if the child object is already loaded and you change its related Id property?
|
|
|
Yes, it is safe to change foreign key (ChildObjectId) properties. However, the associated entity (ChildObject) will only get wired up if the entity (target) is associated with a unit of work; also, if target is associated with a unit of work, but the unit of work is disposed, you may get errors. For example, suppose we have an Order, order, and it is associated with a Customer, bob, whose ID is 123. Suppose there is another Customer, kate, in the system whose ID is 456. Then, assuming that the order is registered with a live unit of work, the two following statements have the same effect: order.CustomerId = 456; // implicitly sets order.Customer to kate In both cases, order is removed from bob's Orders collection and added to kate's Orders collection. Hope that makes sense -- let us know if you need more info or if it's still not clear! |
|
|
yes, thanks, that makes sense and will allow me to 'clone' an object without having to hit the db for every child object since SaveChanges is called immediately after setting all the properties and then the UoW is disposed.
is there a way I can also use this approach for collections that are throughassociations? i.e. i can do this right now to clone a child collection in a separate UoW: newUow = Context.CreateUnitOfWork(); foreach (ChildObject c in source.ChildCollection)
is the following equivalent, but does so without loading all the child objects from DB? newUow = Context.CreateUnitOfWork(); foreach (ChildObject c in source.ChildCollection)
I presume that the ChildCollection property when using throughassociations is just a wrapper to iterate through the ChildObjects of all the items in ObjectChildObject |
|
|
Yes, that looks like it should work. This will of course still load the through objects (the ObjectChildObject entries) from the database, but not the associated ChildObjects. |
|