NHibernate:在更新实体后获取版本属性的增量值
本文关键字:属性 版本 获取 更新 实体 NHibernate | 更新日期: 2023-09-27 18:03:15
假设存在一个实体:
class Book
{
public Guid ID { get; set; }
public int Version { get; set; }
public string Author { get; set; }
public string Title { get; set; }
}
合适的Fluent NHibernate-mapping:
class BookMapping : ClassMap<Book>
{
public BookMapping()
{
Id(x => x.ID).GeneratedBy.GuidComb();
Version(x => x.Version);
Map(x => x.Author);
Map(x => x.Title);
}
}
我想在IStatelessSession.Update()
方法调用Book
实例后获得Version
属性的增量值,以执行另一个实体的相关更新(参见注释):
using (var session = sessionFactory.OpenStatelessSession())
{
using (var transaction = session.BeginTransaction())
{
session.Update(book);
// Is it safe to use the value of the book.Version property here?
//
// Just for example:
// bookReference.ID = book.ID;
// bookReference.Version = book.Version; // I would like to have the latest (incremented) version here.
// session.Insert(bookReference);
transaction.Commit();
}
}
当前调试显示它按预期工作。但是我没有找到说明这种行为的文档,即增加IStatelessSession.Update()
方法调用后的版本值,由NHibernate保证。
- 能否提供相应官方文件的参考?有这样的保证吗?
- 在调用
ITransaction.Commit()
方法之前,哪些方法可以导致Version
的值增加?
上述行为不是随机的。
大于doc
(不确定)可能是为了观察代码。任何实体的更新最后都委托给:
EntityUpdateAction.cs
它的方法 Execute()
如下(只是重要部分)
public override void Execute()
{
... // some importan stuff
// here the UPDATE is executed
if (!veto)
{
persister.Update(id, state, dirtyFields, hasDirtyCollection,
previousState, previousVersion, instance, null, session);
}
EntityEntry entry = Session.PersistenceContext.GetEntry(instance);
if (entry == null)
{
throw new AssertionFailure("Possible nonthreadsafe access to session");
}
// HERE we can see that NHibernate is going for GENERATED properties
// imeditally
if (entry.Status == Status.Loaded || persister.IsVersionPropertyGenerated)
{
// get the updated snapshot of the entity state by cloning current state;
// it is safe to copy in place, since by this time no-one else (should have)
// has a reference to the array
TypeHelper.DeepCopy(state, persister.PropertyTypes,
persister.PropertyCheckability, state, Session);
if (persister.HasUpdateGeneratedProperties)
{
// this entity defines property generation, so process those generated
// values...
persister.ProcessUpdateGeneratedProperties(id, instance, state, Session);
IPersister
方法 ProcessUpdateGeneratedProperties()
描述:
/// <summary>
/// Perform a select to retrieve the values of any generated properties
/// back from the database, injecting these generated values into the
/// given entity as well as writing this state to the persistence context.
/// </summary>
/// <remarks>
/// Note, that because we update the persistence context here, callers
/// need to take care that they have already written the initial snapshot
/// to the persistence context before calling this method.
/// </remarks>
/// <param name="id">The entity's id value.</param>
/// <param name="entity">The entity for which to get the state.</param>
/// <param name="state">The entity state (at the time of Save).</param>
/// <param name="session">The session.</param>
void ProcessUpdateGeneratedProperties(object id, object entity,
object[] state, ISessionImplementor session);
所以,可以肯定的是,你所经历的行为不是随机的。它是由事实驱动的,即有生成的属性——由DB生成。NHibernate总是在每次更新后重新加载这些…
要触摸第二部分,唯一调用它的地方是: session.Flush()
。这可能是提交的一部分,但实际上取决于SessionFlush Mode (甚至可以是 Never
,我们必须/可以手动完成)。无论如何,一旦真正的DB UPDATE被触发,它将进入上述包中,并且我们可以确定,DB生成的属性是最新的