我们假设有一个实体:
class Book
{
public Guid ID { get; set; }
public int Version { get; set; }
public string Author { get; set; }
public string Title { get; set; }
}
适当的Fluent NHibernate映射:
class BookMapping : ClassMap<Book>
{
public BookMapping()
{
Id(x => x.ID).GeneratedBy.GuidComb();
Version(x => x.Version);
Map(x => x.Author);
Map(x => x.Title);
}
}
我希望在Version
实例的IStatelessSession.Update()
方法调用之后获取Book
属性的递增值,以执行另一个实体的相关更新(请参阅注释):< / p>
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保证。
Version
方法之前哪些方法可能导致ITransaction.Commit()
值增加?答案 0 :(得分:2)
上述行为不是随机的。
超过doc
(不确定)可能是观察代码。任何实体的更新最终都委托给:
其方法 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生成的属性是最新的