0

新しいブックマークを作成し、それに 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 を見ると、これは機能しているようです。これが間違っている場合は教えてください:)

4

1 に答える 1