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 try to delete objects from database. Let's assume we DBItem and DBSubItem with strong (not nullable) one-to-many relation. Then we have the code:
// Load Items and SubItems EntityCollection<DBItem> Items = new EntityCollection<DBItem>(); EntityCollection<DBSubItem> SubItems = new EntityCollection<DBSubItem>(); using (var uow = _context.CreateUnitOfWork()) { Items.AddRange(uow.DBItems); SubItems.AddRange(uow.DBSubItems); }
using (var uow = _context.CreateUnitOfWork()) { // ====== That's the code, I have doubts about ======= foreach (var item in Items) uow.Attach(item); foreach (var subItem in SubItems) uow.Attach(subItem); // ===================================================
foreach (var item in tmp) uow.Remove(item); uow.SaveChanges(); }
int itemsCount, subItemsCount; using (var uow = _context.CreateUnitOfWork()) { itemsCount = uow.DBItems.Count(); subItemsCount = uow.DBSubItems.Count(); } I purposely put all the fragments into separate UnitOfWork, because they exist in different methods in the real code. Running such code on not empty database (DBItems and DBSubItems tables are not empty) results with nothing deleted! When I remove the code within '=======' comment, everything works fine. Honestly speaking I expected just the opposite behaviour - when the objects come from another UOW, they could "resist" deletion (I wouldn't mind if they did), but when they are attached to UOW - they should be deleted. Where is the mistake in my analysis? |
|
|
Calling UnitOfWork.Remove(entity) will attach that entity to the UnitOfWork since you have asked that UnitOfWork to remove it. That said, performing an Attach prior will effectively do the same thing (just in a slightly different ordering) and should not affect any behavior of the removal query. I have run up your code here using a fairly simple model replicating what you have described above, and things run as expected which is that the entities are being removed regardless of the attach calls. Are you able to send through a copy of your model and some sample data? If so we can have a bit more of a look into what might be going on here since that doesnt sound right.
Jeremy |
|
|
I attach my example. It is an attempt to use LightSpeed (we call it a prototype), so please excuse me for all the code commented out. To see the described behaviour, please:
The ClearStoreysExecute() in DMPProject.cs is executing the code from my first post. Storey = Item, Appartment = SubItem. |
|
|
Thanks for the sample, I have looked into this and found the cause of the issue. Basically the items are not being removed because they were not in the identity map for that UnitOfWork, why that is however in this particular case hinges on a bug on providers (e.g. SQLite) where Guid values are stored and returned as strings. |
|
|
Thank you very much for your fast reaction. I'll download the nightly build when it's available and check it. However, I have to take a decision whether to use many short-lived UOWs or one UOW (single per program lifetime). Our database usage is quite specific - we'd like to use LightSpeed as data provider for CAD program. In such program almost all the objects can be accessed at any time, and it is very hard to make i.e. UOW for a single form (as it may be used in a typical DB application). So the question is: in your opinion - is it better to keep one UOW for program lifetime (considering the possibility of database connection loss - i.e. as described in http://www.mindscape.co.nz/forums/Thread.aspx?PostID=9811) or to juggle with short-lived UOWs and manually maintaining uow.Attach ? |
|
|
It somewhat depends on the behavior of your application. If your application can expect to be connected (other than in an exception case) then you should use a globally accesible service for managing your UnitOfWork and it would be sensible to implement a custom connection strategy to handle the cases where the database connection is closed or there is a network error etc. Attaching the entity and then re-persisting it via SaveChanges() makes sense if your model is more occasionally connected, but as you say you do have to do more juggling and you may run into issues with lazy loading throwing exceptions because it has be disassociated from its original UnitOfWork.
Jeremy |
|
|
Everything works fine on the nightly build. Thank you. :-) |
|