有时我在log(NHibernate.SQL)中看到,当我提交事务时,此代码会导致实体的update
sql查询。
using (ISession session = SessionFactory.OpenSession())
{
using (session.BeginTransaction())
{
entity = session.Get<E>(id);
session.Transaction.Commit();
}
}
为什么会这样?
堆栈追踪:
at NHibernate.AdoNet.Util.SqlStatementLogger.LogCommand(String message, IDbCommand command, FormatStyle style) in p:\nhibernate-core\src\NHibernate\AdoNet\Util\SqlStatementLogger.cs:line 56
at NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand cmd) in p:\nhibernate-core\src\NHibernate\AdoNet\AbstractBatcher.cs:line 191
at NHibernate.AdoNet.NonBatchingBatcher.AddToBatch(IExpectation expectation) in p:\nhibernate-core\src\NHibernate\AdoNet\NonBatchingBatcher.cs:line 40
at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session) in p:\nhibernate-core\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 2776
at NHibernate.Persister.Entity.AbstractEntityPersister.UpdateOrInsert(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session) in p:\nhibernate-core\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 2702
at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor session) in p:\nhibernate-core\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 2957
at NHibernate.Action.EntityUpdateAction.Execute() in p:\nhibernate-core\src\NHibernate\Action\EntityUpdateAction.cs:line 79
at NHibernate.Engine.ActionQueue.Execute(IExecutable executable) in p:\nhibernate-core\src\NHibernate\Engine\ActionQueue.cs:line 136
at NHibernate.Engine.ActionQueue.ExecuteActions(IList list) in p:\nhibernate-core\src\NHibernate\Engine\ActionQueue.cs:line 125
at NHibernate.Engine.ActionQueue.ExecuteActions() in p:\nhibernate-core\src\NHibernate\Engine\ActionQueue.cs:line 171
at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) in p:\nhibernate-core\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs:line 241
at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) in p:\nhibernate-core\src\NHibernate\Event\Default\DefaultFlushEventListener.cs:line 20
at NHibernate.Impl.SessionImpl.Flush() in p:\nhibernate-core\src\NHibernate\Impl\SessionImpl.cs:line 1507
at NHibernate.Transaction.AdoTransaction.Commit() in p:\nhibernate-core\src\NHibernate\Transaction\AdoTransaction.cs:line 193
更新后的属性如下:
public virtual MyEnum MyProperty { get; set; }
并映射到integer not null
数据库列。
答案 0 :(得分:0)
这是
的结果想象一下,你在DB中有专栏
Age [int] NULL -- Nullable column
但映射说不可为空:
<property name="Age" not-null="true" />
和C#属性也不可为空
public virtual int Age { get; set; }
如果此类记录加载了 null
值,则实体的属性 Age
设置为 0 。
在这种情况下...... NHiberante知道值已经改变,并尝试使用FLUSH(提交)使数据库和应用程序保持一致。这就是执行写操作的原因......只是一个例子,但在坚果壳中就是这些情况
答案 1 :(得分:0)
映射枚举的正确方法是:
public class EnumConvention : IPropertyConvention, IPropertyConventionAcceptance
{
public void Apply(IPropertyInstance instance)
{
instance.CustomType(instance.Property.PropertyType);
}
public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
{
criteria.Expect(x => x.Property != null);
criteria.Expect(x => x.Type.IsEnum);
}
}
这解决了我的问题。