title: Repository pattern and many cascading changes
body: <p>I need to cascade many changes when updating an entity. I could do it like below, but that is ugly imho (too many parameters already and counting).</p>
  
  <pre><code>public class PageRepository : IPageRepository
  {
      public void Update(Page page, string oldPath, PageState oldState, IEnumerable&lt;Tag&gt; 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();
          }
      }
  }
  </code></pre>
  
  <p>Is there any pattern that could help making that cleaner?</p>
  
  <p>I have already thought about splitting that to multiple methods</p>
  
  <pre><code>pageRepo.BeginTransaction();
  pageRepo.Update(page);
  if(/* path has changed */)
  {
      pageRepo.MoveDescendants(page, oldPath);
  }
  // ...
  
  pageRepo.Commit();
  </code></pre>
  
  <p>but I don't like that manual transaction handling. Another idea I got is</p>
  
  <pre><code>using(var batch = pageRepo.CreateUpdateBatch(page))
  {
      if(/* path has changed */)
      {
          batch.MoveDescendants(oldPath);
      }
      // ...
      batch.Commit();
  }
  </code></pre>