Hi,
i have the following situation. In our datamodel we work with articles, and articles can have a parent-child relation with other articles. We implemented this using a table ARTICLE_RELATION with just 2 foreign keys (AR_ID1 & AR_ID2) to the the ARTICLE table. In LLBLGen i mapped the relations with appropriate names so my ArticleEntity has an ArticleChilds and an ArticleParents collection.
Consider the following code:
UnitOfWork uow = new UnitOfWork();
ArticleEntity a1 = new ArticleEntity(1);
ArticleEntity a2 = new ArticleEntity(2);
ArticleRelationEntity r1 = new ArticleRelationEntity();
a1.ArticleChilds.Add(r1);
a2.ArticleParents.Add(r1);
uow.AddForSave(a1,true);
uow.Commit(new Transaction(IsolationLevel.ReadCommitted,"UOW"),true);
//At this point we have a record (1,2) in ARTICLE_RELATION
//re-initialize all unit of work
uow = new UnitOfWork();
a1.ArticleChilds.Remove(r1);
uow.AddForDelete(r1);
uow.AddForSave(a1,true);
uow.Commit(new Transaction(IsolationLevel.ReadCommitted,"UOW"),true);
//At this point we do not have a record (1,2) in ARTICLE_RELATION
//re-initiialize all unit of work
uow = new UnitOfWork();
ArticleRelationEntity r2 = new ArticleRelationEntity();
a1.ArticleChilds.Add(r2);
a2.ArticleParents.Add(r2);
uow.AddForSave(a1,true);
uow.Commit(new Transaction(IsolationLevel.ReadCommitted,"UOW"),true);
//At this point we have a record (1,2) in ARTICLE_RELATION
This works completely as expected. But rearranging some code to :
UnitOfWork uow = new UnitOfWork();
ArticleEntity a1 = new ArticleEntity(1);
ArticleEntity a2 = new ArticleEntity(2);
ArticleRelationEntity r1 = new ArticleRelationEntity();
a1.ArticleChilds.Add(r1);
a2.ArticleParents.Add(r1);
uow.AddForSave(a1,true);
uow.Commit(new Transaction(IsolationLevel.ReadCommitted,"UOW"),true);
//At this point we have a record (1,2) in ARTICLE_RELATION
//re-initialize all unit of work
uow = new UnitOfWork();
a1.ArticleChilds.Remove(r1);
uow.AddForDelete(r1);
ArticleRelationEntity r2 = new ArticleRelationEntity();
a1.ArticleChilds.Add(r2);
a2.ArticleParents.Add(r2);
uow.AddForSave(a1,true);
uow.Commit(new Transaction(IsolationLevel.ReadCommitted,"UOW"),true);
//At this point we SHOULD have a record (1,2) in ARTICLE_RELATION but it crashes ...
gives the following error on the last commit :
An unhandled exception of type 'SD.LLBLGen.Pro.ORMSupportClasses.ORMQueryExecutionException' occurred in sd.llblgen.pro.ormsupportclasses.net11.dll
Additional information: An exception was caught during the execution of an action query: Violation of PRIMARY KEY constraint 'ARTICLE_RELATION_PK'. Cannot insert duplicate key in object 'ARTICLE_RELATION'.
The statement has been terminated.. Check InnerException, QueryExecuted and Parameters of this exception to examine the cause of this exception.
Why is that ? Shouldn't the order of statements added to the UnitOfWork make sure that the (1,2) record is first deleted, and THEN re-added ?
To put this testcase in the realworld application, we can get this situation when a user removes something from a subcollection (it gets added to the unitofwork for delete), then changes his mind and re-adds it to the subcollection, which will be saved when the main object added to the unitofwork and then commited. This strategy is used throughout our application, and gives no problems, except here, so i guess it has something to do with this "selfreferencing".
Version: I'm still using the 2004.2 version (but with the latest templates & runtimes) but I would rather not upgrade to the 2005 for this project, it's almost finished