新しいブックマークを作成し、それに 1 つ以上のタグを追加する次のコードがあります。タグがまだ存在しない場合は、作成されてブックマークに追加されます。
Bookmark bookmark = new Bookmark();
bookmark.Title = request.Title;
bookmark.Link = request.Link;
bookmark.DateCreated = request.DateCreated;
bookmark.DateModified = request.DateCreated;
bookmark.User = _userRepository.GetUserByUsername(request.Username);
IList<Tag> myTags = _tagRepository.GetTags(request.Username);
IList<string> myTagsToString = myTags.Select(x => x.Title).ToList<string>();
foreach (var tag in request.Tags)
{
if (myTagsToString.Contains(tag))
{
Tag oldTag = myTags.SingleOrDefault(x => x.Title == tag);
bookmark.Tags.Add(oldTag);
}
else
{
Tag newTag = new Tag();
newTag.Title = tag;
newTag.User = _userRepository.GetUserByUsername(request.Username);
newTag.DateCreated = request.DateCreated;
newTag.DateModified = request.DateCreated;
bookmark.Tags.Add(newTag);
}
}
_bookmarkRepository.Add(bookmark);
_uow.Commit();
作業単位を実装しましたが、これが正しく行われたかどうかはわかりません。save メソッドの後に commit を使用します。save メソッドはブックマークとタグをデータベースに挿入し、commit メソッドはジャンクション テーブルに挿入します (ブックマークには多くのタグがあり、タグには多くのブックマークがあります)。
したがって、すべてが正しく挿入されます。ただし、 commit メソッドを削除しても、ブックマークとタグは引き続き挿入されます。しかし、それらはジャンクション テーブルへの挿入ではありません。これは、ブックマークとタグをデータベースに保存するためにコミットする必要がないため、これらの挿入が同じトランザクションにないことを意味しますか? コミットは、タグとブックマークの間の関係を保存するためにのみ必要です。
編集:
リポジトリ
public abstract class Repository<T, TEntityKey> where T : IAggregateRoot
{
private IUnitOfWork _uow;
public Repository(IUnitOfWork uow)
{
_uow = uow;
}
public void Save(T entity)
{
SessionFactory.GetCurrentSession().SaveOrUpdate(entity);
}
public void Add(T entity)
{
SessionFactory.GetCurrentSession().Save(entity);
}
public void Remove(T entity)
{
SessionFactory.GetCurrentSession().Delete(entity);
}
public IEnumerable<T> FindAll()
{
ICriteria criteriaQuery = SessionFactory.GetCurrentSession().CreateCriteria(typeof(T));
return (List<T>)criteriaQuery.List<T>();
}
}
UnitOfWork
public class NHUnitOfWork : IUnitOfWork
{
public void RegisterAmended(IAggregateRoot entity)
{
SessionFactory.GetCurrentSession().SaveOrUpdate(entity);
}
public void RegisterNew(IAggregateRoot entity)
{
SessionFactory.GetCurrentSession().Save(entity);
}
public void RegisterRemoved(IAggregateRoot entity)
{
SessionFactory.GetCurrentSession().Delete(entity);
}
public void Commit()
{
using (ITransaction transaction = SessionFactory.GetCurrentSession().BeginTransaction())
{
try
{
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
throw;
}
}
}
}
ブックマークリポジトリ
public class BookmarkRepository : Repository<Bookmark, int>, IBookmarkRepository
{
public BookmarkRepository(IUnitOfWork uow)
: base(uow)
{
}
}
更新: NHUnitOfWork を次のように変更しました:
public class NHUnitOfWork : IUnitOfWork
{
private ITransaction _transaction;
public void RegisterAmended(IAggregateRoot entity)
{
SessionFactory.GetCurrentSession().SaveOrUpdate(entity);
}
public void RegisterNew(IAggregateRoot entity)
{
SessionFactory.GetCurrentSession().Save(entity);
}
public void RegisterRemoved(IAggregateRoot entity)
{
SessionFactory.GetCurrentSession().Delete(entity);
}
public void BeginTransaction()
{
_transaction = SessionFactory.GetCurrentSession().BeginTransaction();
}
public void Commit()
{
using (_transaction)
{
try
{
_transaction.Commit();
}
catch (Exception ex)
{
_transaction.Rollback();
throw;
}
}
}
}
したがって、次のように使用できます。
_uow.BeginTransaction();
Bookmark bookmark = new Bookmark();
bookmark.Title = request.Title;
bookmark.Link = request.Link;
bookmark.DateCreated = request.DateCreated;
bookmark.DateModified = request.DateCreated;
bookmark.User = _userRepository.GetUserByUsername(request.Username);
IList<Tag> myTags = _tagRepository.GetTags(request.Username);
IList<string> myTagsToString = myTags.Select(x => x.Title).ToList<string>();
foreach (var tag in request.Tags)
{
if (myTagsToString.Contains(tag))
{
Tag oldTag = myTags.SingleOrDefault(x => x.Title == tag);
bookmark.Tags.Add(oldTag);
}
else
{
Tag newTag = new Tag();
newTag.Title = tag;
newTag.User = _userRepository.GetUserByUsername(request.Username);
newTag.DateCreated = request.DateCreated;
newTag.DateModified = request.DateCreated;
bookmark.Tags.Add(newTag);
}
}
_bookmarkRepository.Add(bookmark);
_uow.Commit();
NHUnitOfWork 実装に begin トランザクションを追加しました。これは、select または insert の前に _uow.BeginTransaction() を呼び出し、最後に _uow.Commit() を呼び出す必要があることを意味します。NHibernate Profiler を見ると、これは機能しているようです。これが間違っている場合は教えてください:)