0
更新實體時,我需要級聯許多更改。我可以像下面那樣做,但這是醜陋的imho(太多的參數已經和計數)。存儲庫模式和許多級聯更改
public class PageRepository : IPageRepository
{
public void Update(Page page, string oldPath, PageState oldState, IEnumerable<Tag> oldTags /* Maybe even more stuff */)
{
using(var t = session.BeginTransaction())
{
if(/* path has changed */)
{
// move descendant pages
}
if(/* state has changed to public */)
{
// publish hidden descendant pages
}
if(/* state has changed to non-public */)
{
// hide public descendant pages
}
if(page is ITaggable)
{
foreach(var tag in ((ITaggable)page).Tags.Except(oldTags))
{
// increase tag count in ancestor pages
}
foreach(var tag in oldTags.Except(((ITaggable)page).Tags))
{
// decrease tag count in ancestor pages
}
}
// ...
session.Update(page);
t.Commit();
}
}
}
有什麼模式可以幫助使清潔劑?
我已經想過分裂,要多種方法
pageRepo.BeginTransaction();
pageRepo.Update(page);
if(/* path has changed */)
{
pageRepo.MoveDescendants(page, oldPath);
}
// ...
pageRepo.Commit();
,但我不喜歡手動事務處理。我得到的另一個想法是
using(var batch = pageRepo.CreateUpdateBatch(page))
{
if(/* path has changed */)
{
batch.MoveDescendants(oldPath);
}
// ...
batch.Commit();
}
如果最後一步失敗怎麼辦?如果前面的步驟事務沒有了,我怎樣才能回滾更改? –
不要將代碼中的using代碼塊封裝在存儲庫中。相反,在會話周圍包裝IUnitOfWork接口,僅公開BeginTransation()和Commit()方法,然後從存儲庫中公開該接口。這樣,您可以從協調類調用UnitOfWork.BeginTransaction()和UnitOfWork.Commit()方法,而不是從存儲庫中調用。 – danludwig