NHibernate在一个事务中保存并提交
本文关键字:事务 保存 提交 一个 NHibernate | 更新日期: 2023-09-27 18:28:38
我有下面的代码,它创建了一个新的书签,并向其中添加了一个或多个标记。如果标记还不存在,就会创建并添加到书签中。
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方法将书签插入连接表(书签有很多标签,标签有很多书签)。
因此,所有内容都插入正确。但是,如果我删除提交方法,书签和标记仍然会被插入。但它们并没有插入到连接表中。这是否意味着这些插入不在同一事务中,因为将书签和标记保存到数据库不需要提交?提交仅用于保存标记和书签之间的关系。
编辑:
存储库
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 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;
}
}
}
}
BookmarkRepository
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事务。这意味着我需要在任何选择或插入之前调用_uow.BeginTransaction(),并在最后调用_uow.Commit()。如果我查看NHibernate Profiler,这似乎可以工作。如果这是错误的,请告诉我:)
您的Save
方法不会在事务中执行,因为您在Commit
方法中关闭并打开事务。
正确的实现是在调用Save
之前启动事务。