我有一个名为ProjectTaskBudget
的类,它具有IBudgetableIncomeStream
类型的属性,如下所示:
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
继承的具体类是DeliverableItem
和DeliverableTime
。
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()
我想知道将界面直接应用于DeliverableItem
和DeliverableTime
是否有所作为,并且映射包含
.AddMetaValue<DeliverableItem>("DeliverableItem")
.AddMetaValue<DeliverableTime>("DeliverableTime")
但这是一个相当大的重构,所以我想先检查,看看我是否遗漏了更明显的东西,或者听起来像是废话。
答案 0 :(得分:2)
好的,我明白了。问题在于映射,但不是我的想法。
它试图添加的IBudgetableIncomeStream
实际上是
从DeliverableItem
派生的东西,所以映射
DeliverableItem
是不够的,我必须放入每个子类
映射中为DeliverableItem
和DeliverableTime
,例如:
.AddMetaValue<DeliverableItemSubclass1>("DeliverableItemSubclass1")
.AddMetaValue<DeliverableItemSubclass2>("DeliverableItemSubclass2")
.AddMetaValue<DeliverableTimeSubclass1>("DeliverableTimeSubclass1")