问题
I'm trying to update a single column in the table. No UPDATE issued whatsoever (checked using SQL Profiler). No errors.
- Class mapping has
dynamic-update="true"
. - No versioning enabled on the class.
- Flush mode Commit.
- Property mapped without any insert/update modifiers (
<property name="Deleted" />
). - Property is auto-implemented (
public virtual bool Deleted { get;set;}
). NH 3.3.0, .NET 4, x64.
using (var transaction = this._session.BeginTransaction()) { try { var order = this.session.Load<Order>(id); order.Deleted = true; this._session.Update(order); transaction.Commit(); } catch (Exception) { transaction.Rollback(); throw; } }
回答1:
Based on the comments, what you are trying to do is create a proxy without getting the current state from the DB (using session.Load
), then issue a dynamic update.
This will not work. NHibernate does not record individual changes to properties; instead, it:
- Compares the current state of tracked entities against a snapshot of the property values that were retrieved from the database.
- Based on that, determines which entities are dirty (i.e. have changes)
- It generates the SQL update statement. If using
dynamic-update
, it will only contain the modified properties.
If you use session.Load
, as soon as you access the Deleted
property, NH will load the record from the database. Whether you use session.Load
or session.Get
, session.Update
on an already tracked entity is a no-op.
Alternatively, if you already have the state for all the order properties, you can update without loading:
var order = GetTheOrderFromMemory();
order.Deleted = true;
session.Update(order);
transaction.Commit();
This will not respect dynamic-update
, as NH doesn't have a snapshot to compare with...
...which is why HQL is the only way to do a one-shot update of an individual property.
来源:https://stackoverflow.com/questions/21788096/nhibernate-doesnt-save-one-property-only