FluentNHibernate:使用鉴别器映射子集合

时间:2015-02-04 09:33:19

标签: c# fluent-nhibernate mapping discriminator

使用嵌套集合查看我的对象不会抛出错误,但在尝试保存时,我发现了错误

    [IndexOutOfRangeException: Invalid index 15 for SqlParameterCollection with Count=15.]
   System.Data.SqlClient.SqlParameterCollection.RangeCheck(Int32 index) +5343807
   System.Data.SqlClient.SqlParameterCollection.GetParameter(Int32 index) +19
   System.Data.Common.DbParameterCollection.System.Collections.IList.get_Item(Int32 index) +10
   NHibernate.Type.Int64Type.Set(IDbCommand rs, Object value, Int32 index) +60
   NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd, Object value, Int32 index) +414
   NHibernate.Type.NullableType.NullSafeSet(IDbCommand st, Object value, Int32 index, Boolean[] settable, ISessionImplementor session) +62
   NHibernate.Type.ManyToOneType.NullSafeSet(IDbCommand st, Object value, Int32 index, Boolean[] settable, ISessionImplementor session) +122
   NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index) +344

[PropertyValueException: Error dehydrating property value for PravUprav.Classes.Entities.ClaimCaseInstanceFI.Decision]
   NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index) +503
   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) +2013
   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) +335
   NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor session) +1898
   NHibernate.Action.EntityUpdateAction.Execute() +737
   NHibernate.Engine.ActionQueue.Execute(IExecutable executable) +39
   NHibernate.Engine.ActionQueue.ExecuteActions(IList list) +128
   NHibernate.Engine.ActionQueue.ExecuteActions() +48
   NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) +241
   NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) +179
   NHibernate.Impl.SessionImpl.Flush() +295
   NHibernate.Transaction.AdoTransaction.Commit() +189
   Spring.Data.NHibernate.HibernateTransactionManager.DoCommit(DefaultTransactionStatus status) in c:\_prj\spring-net\src\Spring\Spring.Data.NHibernate\Data\NHibernate\HibernateTransactionManager.cs:561

[DataIntegrityViolationException: Error dehydrating property value for PravUprav.Classes.Entities.ClaimCaseInstanceFI.Decision]
   Spring.Data.NHibernate.HibernateTransactionManager.DoCommit(DefaultTransactionStatus status) in c:\_prj\spring-net\src\Spring\Spring.Data.NHibernate\Data\NHibernate\HibernateTransactionManager.cs:577

错误:

Error dehydrating property value for 

说我映射了属性两次或者实体属性的DataTypes不正确,但我检查了并且在我的代码中找不到错误。

收集实体:

public class ClaimCase
{
    private IList<ClaimCaseInstance> _claimCaseInstances;
    public virtual IList<ClaimCaseInstance> ClaimCaseInstances
    {
       get { return _claimCaseInstances ?? (_claimCaseInstances = new List<ClaimCaseInstance>()); }
          set { _claimCaseInstances = value; }
     }
}

实体映射:

public sealed class ClaimCaseMap : ClassMap<ClaimCase>
{
   public ClaimCaseMap()
      {
         Table("ClaimCase");
         Id(x => x.Id);                
         HasMany(x => x.ClaimCaseInstances).Inverse().Cascade.AllDeleteOrphan();
       }
 }

ClaimCaseInstance实体:

public abstract class ClaimCaseInstance
{
    public virtual ClaimCase ClaimCase { get; set; }
    public virtual DicList Result { get; set; }
}

儿童班:

public class ClaimCaseInstanceFI : ClaimCaseInstance
{
    public virtual DicList Decision { get; set; }
}

public class ClaimCaseInstanceAI : ClaimCaseInstance
{
}

映射:

public sealed class ClaimCaseInstanceMap : ClassMap<ClaimCaseInstance>
{
    public ClaimCaseInstanceMap()
    {
        Table("ClaimCaseInstances");
        Id(x => x.Id);            
        DiscriminateSubClassesOnColumn("InstanceType");

        References(x => x.ClaimCase);
        References(x => x.Result);
    }
}

public sealed class ClaimCaseInstanceFIMap : SubclassMap<ClaimCaseInstanceFI>
{
    public ClaimCaseInstanceFIMap()
    {
        DiscriminatorValue((int)CourtTypes.Firts);
        References(x => x.Decision);
    }
}

public sealed class ClaimCaseInstanceAIMap : SubclassMap<ClaimCaseInstanceAI>
{
    public ClaimCaseInstanceAIMap()
    {
        DiscriminatorValue((int)CourtTypes.Appeals);
    }
}

CourtTypes:

public enum CourtTypes
{
    First = 5,
    Appeals = 6
}
按惯例DicList

ForeignKeyConversion引用映射为instance.Property.Name + "ID",并且工作正常。

在编辑字段ClaimCase

后保存Decision时才会出现错误

3 个答案:

答案 0 :(得分:1)

我已经确定了问题的根源。 使用优秀工具dotPeek(感谢@SergSW获取提示)为symbol serverdebug

NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate()

我发现sql语句中更新字段的数量不等于计数

entityMetamodel.PropertySpan

数组entityMetamodel.Properties中的某些字段存在两次。

public sealed class ClaimCaseInstanceMap : ClassMap<ClaimCaseInstance>
    {
        public ClaimCaseInstanceMap()
        {
            Table("ClaimCaseInstances");

            DiscriminateSubClassesOnColumn("InstanceType");

            Id(x => x.Id);  
            References(x => x.ClaimCase);
            Map(x => x.FilingDate);
            References(x => x.Result);
            Map(x => x.PriceResult);
            Map(x => x.ExpenseResult);
            Map(x => x.Comment);
        }
    }

亚类:

public sealed class ClaimCaseInstanceFIMap : SubclassMap<ClaimCaseInstanceFI>
{
    public ClaimCaseInstanceFIMap()
    {
        DiscriminatorValue((int)CourtType.Firts);

        Id(x => x.Id);  
        Map(x => x.Price);
        Map(x => x.Expense);
        References(x => x.Decision);
        References(x => x.Determination);
        Map(x => x.DeterminationDate);
        Map(x => x.CourtDateAct);
        Map(x => x.PriceResult);
        Map(x => x.ExpenseResult);
        Map(x => x.CounterClaimDate);
        Map(x => x.Comment);
    }
}

如您所见,此属性:CommentExpenseResultPriceResult

我没有描述我问题中所有字段的映射,这是我的错误,对不起,谢谢你的帮助。

答案 1 :(得分:0)

[IndexOutOfRangeException: Invalid index 15 for SqlParameterCollection with Count=15.]

看起来生成的SQL请求存在问题。 你能否展示一下这个案例的SQL语句?

答案 2 :(得分:0)

批处理命令: 命令0:

批处理命令:

命令0:UPDATE ClaimCase SET CreatedDate = @ p0,IsHidden = @ p1,InnerNumber = @ p2,OdpNumber = @ p3,DocumentsDeliveryDate = @ p4,CourtPostDate = @ p5,IncomingClaimDate = @ p6,DisputeDescription = @ p7,LawsuitNumber = @ p8,TotalPriceResult = @ p9,Note = @ p10,CourtSector = @ p11,CaseClosed = @ p12,IsBankrupt = @ p13,BankruptDate = @ p14,CreatedBy = @ p15,CaseCategoryID = @ p16,ClaimDirection = @ p17,ForeignCuratorID = @ p18,InnerContractCuratorID = @ p19,DisputeID = @ p20,CourtID = @ p21,CourtDistrictID = @ p22,MunicipalContractID = @ p23,BelongToDepartmentID = @ p24 WHERE Id = @ p25; @ p0 = 06.05.2014 9:59:56 [Type:DateTime(0)],@ p1 = False [Type:Boolean(0)],@ p2 ='БИС-7/2014'[Type:String(4000)],@ p3 ='5345345'[类型:字符串(4000)],@ p4 = 15.05.2014 0:00:00 [类型:日期时间(0)],@ p5 = 17.05.2014 0:00:00 [类型:日期时间(0)],@ p6 = 08.05 .2014 0:00:00 [类型:日期时间(0)],@ p7 ='предметспора。' [Type:String(4000)],@ p8 ='534534'[Type:String(4000)],@ p9 = 100,00 [Type:Decimal(0)],@ p10 = NULL [Type:String(4000) ],@ p11 = NULL [Type:String(4000)],@ p12 = False [Type:Boolean(0)],@ p13 = False [Type:Boolean(0)],@ p14 = NULL [Type:DateTime( 0)],@ p15 = 7026 [类型:Int64(0)],@ p16 = 23 [类型:Int64(0)],@ p17 = 28 [类型:Int64(0)],@ p18 = 7026 [类型: Int64(0)],@ p19 = 19 [类型:Int64(0)],@ p20 = 14 [类型:Int64(0)],@ p21 = 35 [类型:Int64(0)],@ p22 = 86 [类型:Int64(0)],@ p23 = 2 [类型:Int64(0)],@ p24 = 2027 [类型:Int64(0)],@ p25 = 12347 [类型:Int64(0)]

接下来:

Could not synchronize database state with session

NHibernate.PropertyValueException: Error dehydrating property value for PravUprav.Classes.Entities.ClaimCaseInstanceFI.Decision ---> System.IndexOutOfRangeException: Недопустимый индекс 16 для SqlParameterCollection с Count=16.