nhibernate是否应该在“SaveOrUpdate”后明确刷新会话?
我写了一个失败的集成测试:
[Test]
public void Find_WorkItemWithMatchingDescriptionExistsInRepository_ReturnsWorkItem()
{
// arrange
WorkItemRepository repository = new WorkItemRepository(IsolatingFactory);
const string Description = "A";
WorkItem itemWithMatchingDescription = WorkItem.Create(1, Description);
repository.Commit(itemWithMatchingDescription);
// act
List<WorkItem> searchResult = repository.Find(Description);
// assert
CollectionAssert.Contains(searchResult, itemWithMatchingDescription);
}
在观察nhibernate的sql输出时,我注意到它为repository.Find()操作创建了一个select语句,但在select之前没有插入操作。 如果我在repository.Commit之后放置一个明确的session.Flush(),它按预期工作,但我发现这种行为很奇怪。 为什么在挂起插入和针对会话执行查询时,nhibernate不会自动刷新会话?
我在文档中找到了这个:
9.6。 红晕
有时,ISession将执行将ADO.NET连接的状态与内存中的对象状态同步所需的SQL语句。 这个过程,刷新,默认情况下发生在以下几点
* from some invocations of Find() or Enumerable()
* from NHibernate.ITransaction.Commit()
* from ISession.Flush()
它看起来像默认的nhibernate行为是在find查询之前刷新。 我的存储库使用Ling来查询规范nhibernate,也许这是一个错误。
更新
如果我改变我的映射:
public WorkItemClassMap()
{
Not.LazyLoad();
Id(wi => wi.Id).GeneratedBy.Assigned();
Map(wi => wi.Description).Length(500);
Version(wi => wi.LastChanged).UnsavedValue(new DateTime().ToString());
}
至:
public WorkItemClassMap()
{
Not.LazyLoad();
Id(wi => wi.Id).GeneratedBy.Identity();
Map(wi => wi.Description).Length(500);
}
它按预期工作(在执行查询之前,nhibernate会将插入刷新到数据库)。 我看不到这种行为的任何好理由,所以我假设它有一个错误。 看起来像在我的存储库查询之前需要手动刷新,这并不是我真正想做的事情。
您的示例中的WorkItem是否使用复合ID映射? 我刚刚编写了一个简单的测试。 当我拥有单个标识列时,我的虚拟类将自动刷新。 我用复合ID编写了相同的测试,并获得了上面描述的行为。
您应该为插入和选择方法使用不同的ISession
实例。 如果这些会话位于using
块中,以便它们在数据库事务中正确处理并处理,那么最好:
using (var session = sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
// perform your insert here
tx.Commit();
}
假定您的资源库枯萎或创建一个已经存在的会话。 当您制作WorkItem并提交它时,它只会列出该会话要执行的作业列表。 如果你的仓库没有创建一个事务,而你的commit方法没有明确地提交这个事务。 然后,更新或保存将等待直到会话关闭,因此虽然您可以看到您创建的对象,但是直到您关闭会话或清除会话之前,您将无法获得范围标识。 当然searchResult不会知道任何关于你创建的对象而没有刷新或关闭事务。
交易中存在与交易一样的风险,但如果您正在创建新对象,则应该使用明确的交易。 NHProfiler会很乐意提醒你。
链接地址: http://www.djcxy.com/p/23231.html上一篇: nhibernate should i flush session explicitly after "SaveOrUpdate"?
下一篇: NHibernate ISession Flush: Where and when to use it, and why?