FluentNHibernate:使用鉴别器映射 child 集合
FluentNHibernate: mapping child collection with discriminator
使用嵌套集合查看我的 object 不会引发错误,但是在尝试 保存 实体时出现错误
[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; }
}
Child 类:
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);
}
}
法院类型:
public enum CourtTypes
{
First = 5,
Appeals = 6
}
DicList
按照惯例 ForeignKeyConversion
引用映射为 instance.Property.Name + "ID"
,它工作正常。
仅在编辑字段 Decision
后保存 ClaimCase
时出错
[IndexOutOfRangeException: Invalid index 15 for SqlParameterCollection with Count=15.]
生成的 SQL 请求似乎有问题。
你能展示这个案例的 SQL 声明吗?
批处理命令:
命令 0:
批处理命令:
command 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 [类型:日期时间 (0)],@p1 = False [类型:布尔值 (0)],@p2 = 'БИС-7/2014' [类型:字符串 (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 [类型:DateTime (0)],@p7 = 'предмет спора.' [类型:字符串 (4000)],@p8 = '534534' [类型:字符串 (4000)],@p9 = 100,00 [类型:十进制 (0)],@p10 = NULL [类型:字符串 (4000) ], @p11 = NULL [类型: String (4000)], @p12 = False [类型: Boolean (0)], @p13 = False [类型: Boolean (0)], @p14 = NULL [类型: 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.
我已经确定了问题的根源。
使用好工具 dotPeek (thanks @SergSW for the tip) as symbol server and debug
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);
}
}
如您所见,此属性:Comment
、ExpenseResult
、PriceResult
。
我没有描述问题中所有字段的映射,这是我的错误,对此深表歉意,感谢您的帮助。
使用嵌套集合查看我的 object 不会引发错误,但是在尝试 保存 实体时出现错误
[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; }
}
Child 类:
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);
}
}
法院类型:
public enum CourtTypes
{
First = 5,
Appeals = 6
}
DicList
按照惯例 ForeignKeyConversion
引用映射为 instance.Property.Name + "ID"
,它工作正常。
仅在编辑字段 Decision
ClaimCase
时出错
[IndexOutOfRangeException: Invalid index 15 for SqlParameterCollection with Count=15.]
生成的 SQL 请求似乎有问题。 你能展示这个案例的 SQL 声明吗?
批处理命令: 命令 0:
批处理命令:
command 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 [类型:日期时间 (0)],@p1 = False [类型:布尔值 (0)],@p2 = 'БИС-7/2014' [类型:字符串 (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 [类型:DateTime (0)],@p7 = 'предмет спора.' [类型:字符串 (4000)],@p8 = '534534' [类型:字符串 (4000)],@p9 = 100,00 [类型:十进制 (0)],@p10 = NULL [类型:字符串 (4000) ], @p11 = NULL [类型: String (4000)], @p12 = False [类型: Boolean (0)], @p13 = False [类型: Boolean (0)], @p14 = NULL [类型: 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.
我已经确定了问题的根源。 使用好工具 dotPeek (thanks @SergSW for the tip) as symbol server and debug
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);
}
}
如您所见,此属性:Comment
、ExpenseResult
、PriceResult
。
我没有描述问题中所有字段的映射,这是我的错误,对此深表歉意,感谢您的帮助。