C# NHibernate在一个事务中保存和提交

C# NHibernate在一个事务中保存和提交,c#,nhibernate,unit-of-work,C#,Nhibernate,Unit Of Work,下面的代码创建了一个新书签,并向其中添加了一个或多个标记。如果标记尚不存在,则会创建该标记并将其添加到书签中 Bookmark bookmark = new Bookmark(); bookmark.Title = request.Title; bookmark.Link = request.Link; bookmark.DateCreated = request.DateCreated; bookmark.DateModified = request.DateCreated; bookmark

下面的代码创建了一个新书签,并向其中添加了一个或多个标记。如果标记尚不存在,则会创建该标记并将其添加到书签中

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();
书签存储库

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>();
    }
}
public class BookmarkRepository : Repository<Bookmark, int>, IBookmarkRepository
{
    public BookmarkRepository(IUnitOfWork uow)
        : base(uow)
    {
    }
}
所以我可以这样使用它:

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();
\u uow.BeginTransaction();
Bookmark Bookmark=新书签();
bookmark.Title=request.Title;
bookmark.Link=request.Link;
bookmark.DateCreated=request.DateCreated;
bookmark.DateModified=request.DateCreated;
bookmark.User=\u userRepository.GetUserByUsername(request.Username);
IList myTags=\u tagRepository.GetTags(request.Username);
IList myTagsToString=myTags.Select(x=>x.Title.ToList();
foreach(request.Tags中的var标记)
{
if(myTagsToString.Contains(标记))
{
tagoldtag=myTags.SingleOrDefault(x=>x.Title==Tag);
bookmark.Tags.Add(oldTag);
}
其他的
{
标签newTag=新标签();
newTag.Title=标签;
newTag.User=\u userRepository.GetUserByUsername(request.Username);
newTag.DateCreated=request.DateCreated;
newTag.DateModified=request.DateCreated;
bookmark.Tags.Add(newTag);
}
}
_bookmarkstorepository.Add(书签);
_提交();

我在NHUnitOfWork实现中添加了一个begin事务。这意味着我需要在任何select或insert之前调用_uow.BeginTransaction(),并在最后调用_uow.Commit()。如果我看一下NHibernate分析器,这似乎是可行的。如果这是错误的,请告诉我:)

您的
保存
方法不会在事务内部执行,因为您在
提交
方法中关闭和打开事务


正确的实现是在调用
Save

之前启动事务。为了澄清,正确的实现是在进行任何更改之前启动事务(包括Save(),但也包括Get()+属性修改,因为NHibernate可以(使用默认设置)决定随时执行数据库更改。@Oskar:你有这样的例子吗?我知道Oracle中用于提交之前访问的ID的序列,但我不知道还有其他类似的情况。实际上,从NHibernate来看,它不是“在任何时候”-但从复杂应用程序的角度来看,很难控制何时传输准确的修改。关键是提交()只是触发Flush()的一种可能方式。请参阅参考,了解Flush()何时可以自动发生:从该参考部分,我们还了解到Save())只有在需要获取主键的情况下才会立即插入。我更新了我的问题。我希望这是正确的方法,但似乎有效。
_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();