如何使Nhibernate不将对象中的更改持久化到数据库
在运行集成测试的数据库中有一组数据。为了防止数据库中的NHibernate持久化对象修改,实现了从DefaultSaveOrUpdateEventListener继承的EventListener 还有一种方法:如何使Nhibernate不将对象中的更改持久化到数据库,nhibernate,Nhibernate,在运行集成测试的数据库中有一组数据。为了防止数据库中的NHibernate持久化对象修改,实现了从DefaultSaveOrUpdateEventListener继承的EventListener 还有一种方法: public override void OnSaveOrUpdate(SaveOrUpdateEvent @event) { @event.Session.CancelQuery(); Trace.TraceWarning("NhibernateSaveUpdateCancel
public override void OnSaveOrUpdate(SaveOrUpdateEvent @event)
{
@event.Session.CancelQuery();
Trace.TraceWarning("NhibernateSaveUpdateCanceler: Persistence will be ignored.");
}
不幸的是,这并不像预期的那样有效。因此,预期的行为是捕捉在数据库中写入更改的时刻,并以某种方式取消更改,尽管将对象保留为存在,以便可以验证对它们的修改
谢谢
编辑
无法执行此操作,因为测试方法中存在多个事务,因此通过持久化更改存在需求矛盾,因此一方的所有事务都可用,而另一方的更改不会持久化到数据库中。当调用
session.Save
或session.Update
。刷新更改时,将为每个实体调用FlusEntity事件。实现iLushEntityEventListener
在调用会话时调用Save或Update事件侦听器。Save
或会话。Update
。刷新更改时,将为每个实体调用FlusEntity事件。实现iLushEntityEventListener
使用集成测试夹具库重新编写集成测试。在基类中创建:
初始化nhibernate并创建会话工厂的装置设置
关闭会话工厂的夹具拆卸
创建会话和事务的测试设置
回滚事务并关闭会话的测试拆卸
像这样
[TestFixture]
public abstract class TestFixtureBase
{
protected ISessionFactory SessionFactory { get; private set; }
protected ISession Session { get; private set; }
protected ITransaction Tx { get; private set; }
[TestFixtureSetUp]
public virtual void SetUp()
{
var nh = new NHInit();
nh.Initialize();
SessionFactory = nh.SessionFactory;
}
[TestFixtureTearDown]
public virtual void TearDown()
{
SessionFactory.Close();
}
[SetUp]
public void Test_Set_Up()
{
Session = SessionFactory.OpenSession();
Tx = Session.BeginTransaction();
}
[TearDown]
public void Test_tear_down()
{
Tx.Rollback();
Tx.Dispose();
Session.Close();
}
}
然后编写测试。使用集成测试夹具底座重新编写集成测试。在基类中创建: 初始化nhibernate并创建会话工厂的装置设置 关闭会话工厂的夹具拆卸 创建会话和事务的测试设置 回滚事务并关闭会话的测试拆卸 像这样
[TestFixture]
public abstract class TestFixtureBase
{
protected ISessionFactory SessionFactory { get; private set; }
protected ISession Session { get; private set; }
protected ITransaction Tx { get; private set; }
[TestFixtureSetUp]
public virtual void SetUp()
{
var nh = new NHInit();
nh.Initialize();
SessionFactory = nh.SessionFactory;
}
[TestFixtureTearDown]
public virtual void TearDown()
{
SessionFactory.Close();
}
[SetUp]
public void Test_Set_Up()
{
Session = SessionFactory.OpenSession();
Tx = Session.BeginTransaction();
}
[TearDown]
public void Test_tear_down()
{
Tx.Rollback();
Tx.Dispose();
Session.Close();
}
}
然后编写您的测试。目的是进行集成测试,允许检查要修改的对象,但其更改不会反映在数据库中,从而允许在同一组数据上运行多个测试。。。。但是如何对多个事务运行测试呢?你在评论弗兰的回答时提到了这一点。这不行。更重要的是:在同一事务中,NH需要刷新更改以使后续查询正常工作。如果你抑制潮红,你会打破它的。斯蒂芬,你是对的。如果在另一个事务中使用临时对象,则数据库查询将返回旧数据,因此更改将丢失。我最终取消了test in TearDown方法引入的更改。我正在内存中的sqlite数据库上运行测试。它非常快。我为每个测试创建了一个全新的数据库。在测试过程中,您只需要保持一个连接处于打开状态,就可以使db保持活动状态。并且只创建一次会话工厂,因为这很慢。其目的是进行集成测试,允许检查对象进行修改,但其更改不会反映在数据库中,从而允许在同一组数据上运行多个测试。。。。但是如何对多个事务运行测试呢?你在评论弗兰的回答时提到了这一点。这不行。更重要的是:在同一事务中,NH需要刷新更改以使后续查询正常工作。如果你抑制潮红,你会打破它的。斯蒂芬,你是对的。如果在另一个事务中使用临时对象,则数据库查询将返回旧数据,因此更改将丢失。我最终取消了test in TearDown方法引入的更改。我正在内存中的sqlite数据库上运行测试。它非常快。我为每个测试创建了一个全新的数据库。在测试过程中,您只需要保持一个连接处于打开状态,就可以使db保持活动状态。只创建一次会话工厂,因为这很慢。不幸的是,我不能这样做,因为测试代码中有多个事务。虽然在测试较小的功能块时这是一个好主意。不幸的是,我不能这样做,因为测试代码中有多个事务。尽管在测试较小的功能块时,这是一个好主意。