在存储库中公开事务.NHibernate
本文关键字:事务 NHibernate 存储 | 更新日期: 2023-09-27 18:25:45
所以目前我有这样一个存储库实现:
public class Repository<T> : IRepository<T> where T : AbstractEntity<T>, IAggregateRoot
{
private ISession session;
public Repository(ISession session)
{
this.session = session;
}
public T Get(Guid id)
{
return this.session.Get<T>(id);
}
public IQueryable<T> Get(Expression<Func<T, Boolean>> predicate)
{
return this.session.Query<T>().Where(predicate);
}
public IQueryable<T> Get()
{
return this.session.Query<T>();
}
public T Load(Guid id)
{
return this.session.Load<T>(id);
}
public void Add(T entity)
{
using(var transaction = this.session.BeginTransaction())
{
this.session.Save(entity);
transaction.Commit();
}
}
public void Remove(T entity)
{
using(var transaction = this.session.BeginTransaction())
{
this.session.Delete(entity);
transaction.Commit();
}
}
public void Remove(Guid id)
{
using(var transaction = this.session.BeginTransaction())
{
this.session.Delete(this.session.Load<T>(id));
transaction.Commit();
}
}
public void Update(T entity)
{
using(var transaction = this.session.BeginTransaction())
{
this.session.Update(entity);
transaction.Commit();
}
}
public void Update(Guid id)
{
using(var transaction = this.session.BeginTransaction())
{
this.session.Update(this.session.Load<T>(id));
transaction.Commit();
}
}
}
然后我像这样使用Ninject
模块。
public class DataAccessModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
this.Bind<ISessionFactory>()
.ToMethod(c => new Configuration().Configure().BuildSessionFactory())
.InSingletonScope();
this.Bind<ISession>()
.ToMethod(ctx => ctx.Kernel.TryGet<ISessionFactory>().OpenSession())
.InRequestScope();
this.Bind(typeof(IRepository<>)).To(typeof(Repository<>));
}
}
模式导出和更新的调用类似于测试:
[TestFixture]
public class SchemaManipulations
{
[Test]
[Ignore]
public void CreateDatabaseSchema()
{
new SchemaExport(new Configuration().Configure()).Create(false, true);
}
[Test]
[Ignore]
public void UpdateDatabaseSchema()
{
new SchemaUpdate(new Configuration().Configure()).Execute(false, true);
}
}
我保持"干净"我的域层:验证逻辑是用FluentValidation
实现的,它不知道NHibernate
,也不知道其他任何东西。
这对我来说似乎很完美……直到我想知道如何实现版本并发。我选择使用optimistic-locking
,至于为NH
正确映射它,这不是问题。我需要知道如何处理事务,在编辑locked
项目时如何通知用户?
因此,针对长会话的版本并发控制又出现了一个问题。NHibernate。ASP.NET MVC,据说不建议在Repository
上公开事务。
问题本身
我已经听说过SharpArchitecture
和UOW
。这已经足够了。
但我对我的数据访问策略解决方案中提供的问题很感兴趣:这样使用它会面临什么错误/故障?
使用Kaleb Pederson
NHibernate提出的事务和TransactionScope方法是否也是一种解决方案?
谢谢!
您将如何编写这样的代码?
// Save both together or none of it
rep1.Save(newSomeEntity);
rep2.Save(SomeOtherEntity);
不在储存库中很容易
var rep1 = new Repository<SomeEntity>(session);
var rep2 = new Repository<SomeOtherEntity>(session);
using (var tx = session.BeginTransaction())
{
try
{
rep1.Save(newSomeEntity);
rep2.Save(SomeOtherEntity);
tx.Commit();
}
catch (SomeException ex)
{
Handle(ex);
tx.RollBack();
}
}