2

我有一個叫ProjectTaskBudget類具有IBudgetableIncomeStream類型的屬性,像這樣:流利的NHibernate - 錯誤的脫水屬性值;給定鍵不存在在詞典

public class ProjectTaskBudget 
{ 
    public virtual IBudgetableIncomeStream BudgetableIncomeStream { get; set; } 
} 

IBudgetableIncomeStream是套用至,除其他事項外接口,叫做抽象類Deliverable

public abstract class Deliverable : IBudgetableIncomeStream 
{ 
    // Some stuff 
} 

和具體類稱爲RecurringIncomeLine

public class RecurringIncomeLine : IBudgetableIncomeStream 
{ 
    // Some stuff 
} 

Deliverable繼承的具體類是DeliverableItemDeliverableTime

ProjectTaskBudget的映射是這樣的:

public class ProjectTaskBudgetMap : MappingBase<ProjectTaskBudget> 
{ 
    public ProjectTaskBudgetMap() 
    { 
     ReferencesAny(n => n.BudgetableIncomeStream) 
      .EntityTypeColumn("IncomeStreamType") 
      .EntityIdentifierColumn("IncomeStream_id") 
      .AddMetaValue<Deliverable>("Deliverable") 
      .AddMetaValue<RecurringIncomeLine>("RecurringIncomeLine") 
      .IdentityType<Guid>(); 
    } 
} 

這工作,因爲它應該與RecurringIncomeLine,所以我懷疑問題是與抽象/接口映射做。 當我嘗試新的ProjectTaskBudget添加到使用Deliverable數據庫,同花順,我得到這個錯誤:

NHibernate.PropertyValueException: Error dehydrating property value for xxx.xxx.xxx.ProjectTaskBudget.BudgetableIncomeStream ---> System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary. 
    at System.Collections.Generic.Dictionary`2.get_Item(TKey key) 
    at NHibernate.Type.MetaType.NullSafeSet(IDbCommand st, Object value, Int32 index, ISessionImplementor session) 
    at NHibernate.Type.AnyType.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) 
    --- End of inner exception stack trace --- 
    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.Insert(Object id, Object[] fields, Boolean[] notNull, Int32 j, SqlCommandInfo sql, Object obj, ISessionImplementor session) 
    at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id, Object[] fields, Object obj, ISessionImplementor session) 
    at NHibernate.Action.EntityInsertAction.Execute() 
    at NHibernate.Engine.ActionQueue.Execute(IExecutable executable) 
    at NHibernate.Engine.ActionQueue.ExecuteActions(IList list) 
    at NHibernate.Engine.ActionQueue.ExecuteActions() 
    at hiJump.Infrastructure.DataAccess.EventListeners.FixedDefaultFlushEventListener.PerformExecutions(IEventSource session) in c:\code\Git\Harmony\SharedCode\hiJump\hiJump.Infrastructure\DataAccess\EventListeners\FixedDefaultFlushEventListener.cs:line 35 
    at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) 
    at NHibernate.Impl.SessionImpl.Flush() 

我想知道如果直接應用接口DeliverableItemDeliverableTime會有所作爲,並有映射包括

.AddMetaValue<DeliverableItem>("DeliverableItem") 
.AddMetaValue<DeliverableTime>("DeliverableTime") 

但是這是一個相當大的重構,所以我想先檢查,看看我是缺少什麼更明顯,或者如果聽起來像廢話。

+0

它的工作,如果你只是刪除'.AddMetaValue ( 「交付」)'和'添加.AddMetaValue ( 「DeliverableItem」)'和'.AddMetaValue ( 「DeliverableTime」)'不實際改變班級?更改類應該是不必要的,因爲它們已經通過它們的基類實現了'IBudgetableIncomeStream'。 – 2013-02-14 10:18:36

+0

我曾嘗試過,忘記提及它會返回相同的錯誤。 – 2013-02-14 10:23:38

+0

請確保NHibernate不會將'Deliverable'保存到自己的表中。 – 2013-02-14 10:26:43

回答

1

好的,我想通了。問題在於映射,但不是我的想法。

IBudgetableIncomeStream它試圖增加實際上 的東西,從DeliverableItem得來,所以映射 DeliverableItem是不夠的,我必須把在映射的 DeliverableItemDeliverableTime每個子類中,如:

.AddMetaValue<DeliverableItemSubclass1>("DeliverableItemSubclass1") 
.AddMetaValue<DeliverableItemSubclass2>("DeliverableItemSubclass2") 
.AddMetaValue<DeliverableTimeSubclass1>("DeliverableTimeSubclass1") 
相關問題