C# NHibernate - 脱水属性值时出错

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11482106/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 18:00:55  来源:igfitidea点击:

NHibernate - Error dehydrating property value

c#nhibernate

提问by kagundajm

I am getting the error Error dehydrating property value for while committing during update. I have searched and it looks similar to NHibernate: Error dehydrating property - What the heck is this?the only difference being that in the refered question NHibernate was complaining of Unable to resolve property

我在更新期间提交时收到错误脱水属性值错误。我已经搜索过,它看起来类似于NHibernate: Error dehydrating property - 这到底是什么?唯一的区别是在提到的问题 NHibernate 抱怨无法解决财产

Value for IssuingOffice is already existing in the database so it cannot be an issue of referencing an un-saved record

IssuingOffice 的值已存在于数据库中,因此不会是引用未保存记录的问题

The following is the detailed error.

以下是详细错误。

Test 'Tests.Services.StickerInvoiceServiceTests.update_sticker_info_succeeds' failed:
NHibernate.PropertyValueException : Error dehydrating property value for
Model.StickerInvoice.StickerIssuingOffice
----> NHibernate.TransientObjectException : object references an unsaved transient 
instance - save the transient instance before flushing or set cascade action for the property to something that would make it autosave. Type: Model.IssuingOffice, Entity: Model.IssuingOffice
at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index)
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)
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)
at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor session)
at NHibernate.Action.EntityUpdateAction.Execute()
at NHibernate.Engine.ActionQueue.Execute(IExecutable executable)
at NHibernate.Engine.ActionQueue.ExecuteActions(IList list)
at NHibernate.Engine.ActionQueue.ExecuteActions()
at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)
at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event)
at NHibernate.Impl.SessionImpl.Flush()
at NHibernate.Transaction.AdoTransaction.Commit()
UnitOfWork.cs(39,0): at NhRepository.UnitOfWork.Commit()
StickerInvoiceService.cs(73,0): at Services.StickerInvoiceService.UpdateStickerInfo(StickerInvoice entity, IEnumerable`1& brokenRules)
Services\StickerInvoiceServiceTests.cs(131,0): at Tests.Services.StickerInvoiceServiceTests.update_sticker_info_succeeds()
--TransientObjectException
at NHibernate.Engine.ForeignKeys.GetEntityIdentifierIfNotUnsaved(String entityName, Object entity, ISessionImplementor session)
at NHibernate.Type.EntityType.GetIdentifier(Object value, ISessionImplementor session)
at NHibernate.Type.ManyToOneType.NullSafeSet(IDbCommand st, Object value, Int32 index, Boolean[] settable, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index)

Mapping for IssuingOffice

签发办公室的映射

<class name="IssuingOffice" table="IssuingOffice">
<id name="Id">
  <generator class ="hilo">
    <param name ="table">IdGenerator</param>
    <param name ="column">NextHigh</param>
    <param name ="max_lo">2</param>
    <param name ="where">TableKey = 'IssuingOffice'</param>
  </generator>
</id>
<version name="Version" column="Version" />
<property name ="Name" length="150" not-null="true" unique="true" />
<bag name ="IssuedStickers" table ="StickerInvoice" generic="true" inverse="true">
  <key column ="StickerIssuingOfficeId" />
  <one-to-many class ="StickerInvoice"/>
</bag>

Schema for IssuingOffice

签发办公室的架构

CREATE TABLE IssuingOffice(
 Id   int  NOT NULL,
 Name   nvarchar (150) NOT NULL,
 Version   int  NOT NULL,
   CONSTRAINT  PK_IssuingOffice  PRIMARY KEY ( Id  ASC )
 ) 

Mapping for StickerInvoice

StickerInvoice 的映射

<class name="StickerInvoice" table="StickerInvoice">
<id name="Id">
  <generator class ="hilo">
    <param name ="table">IdGenerator</param>
    <param name ="column">NextHigh</param>
    <param name ="max_lo">5</param>
    <param name ="where">TableKey = 'StickerInvoice'</param>
  </generator>
</id>
<version name ="Version" />
<property name ="RefNo" length="50" not-null="true" />
<property name ="Period" not-null="true" />
<property name ="Amount" not-null="true"/>
<property name ="DueDate" not-null="true"/>
<property name ="Penalty" not-null="true"/>
<property name ="InvoiceNo" length="50"/>
<property name ="DateIssued" />
<property name ="ReceiptNo" length="50" />
<property name ="DatePaid" />
<property name ="StickerNo" length="50" />
<many-to-one name ="Vehicle" class="Vehicle" column ="VehicleId" />
<many-to-one name ="StickerIssuedBy" class="User" column ="StickerIssuedById" />
<many-to-one name ="StickerIssuingOffice" class="IssuingOffice" column ="StickerIssuingOfficeId" />

Schema for StickerInvoice

StickerInvoice 的架构

CREATE TABLE StickerInvoice(
    Id int NOT NULL,
RefNo nvarchar(50) NOT NULL,
VehicleId int NOT NULL,
DateIssued datetime NOT NULL,
Period datetime NOT NULL,
Amount decimal(18, 0) NOT NULL,
DueDate datetime NOT NULL,
Penalty decimal(18, 0) NOT NULL,
InvoiceNo nvarchar(50) NULL,
ReceiptNo nvarchar(50) NULL,
DatePaid datetime NULL,
StickerNo nvarchar(50) NULL,
StickerIssuedById int NULL,
StickerIssuingOfficeId int NULL,
Version int NOT NULL,
  CONSTRAINT PK_StickerInvoice PRIMARY KEY ( Id ASC )
)  

I tried for datatype mismatches or repeated properties but found none.

我尝试了数据类型不匹配或重复属性,但没有找到。

Any assistance will be appreciated.

任何帮助将不胜感激。

采纳答案by Miroslav Popovic

If you take a look at your exception more carefully, you'll see this error:

如果您更仔细地查看您的异常,您将看到以下错误:

NHibernate.TransientObjectException : object references an unsaved transient instance - save the transient instance before flushing or set cascade action for the property to something that would make it autosave. Type: Model.IssuingOffice, Entity: Model.IssuingOffice

NHibernate.TransientObjectException :对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例或将属性的级联操作设置为使其自动保存的内容。类型:Model.IssuingOffice,实体:Model.IssuingOffice

Basically, looks like you are trying to save the IssuingOfficecontaining one or more unsaved StickerInvoice. You need to set the cascading optionto IssuingOfficebag mapping.

基本上,看起来您正在尝试保存IssuingOffice包含一个或多个未保存的StickerInvoice. 您需要将级联选项设置为IssuingOffice包映射。

<bag name="IssuedStickers" table="StickerInvoice" 
     generic="true" inverse="true" cascade="save-update">
  <key column="StickerIssuingOfficeId" />
  <one-to-many class="StickerInvoice"/>
</bag>

回答by Vedran

I resolved this exception by setting ReadOnly flag of the many-to-one part of the relation:

我通过设置关系的多对一部分的 ReadOnly 标志解决了这个异常:

References(x => x.Parent).ReadOnly();