2010-04-12 65 views
8

尝试使用nhibernate更新对象时出现以下错误。我试图更新一个外键的字段。任何想法,为什么我可能会得到这个错误?我无法从该错误中找出它,并且我的log4net日志也没有提供任何提示。参数索引超出范围

感谢

System.IndexOutOfRangeException was unhandled by user code 
    Message="Parameter index is out of range." 
    Source="MySql.Data" 
    StackTrace: 
     at MySql.Data.MySqlClient.MySqlParameterCollection.CheckIndex(Int32 index) 
     at MySql.Data.MySqlClient.MySqlParameterCollection.GetParameter(Int32 index) 
     at System.Data.Common.DbParameterCollection.System.Collections.IList.get_Item(Int32 index) 
     at NHibernate.Type.Int32Type.Set(IDbCommand rs, Object value, Int32 index) 
     at NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd, Object value, Int32 index) 
     at NHibernate.Type.NullableType.NullSafeSet(IDbCommand st, Object value, Int32 index, 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) 
     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() 
     at DataAccessLayer.NHibernateDataProvider.UpdateItem_temp(items_temp item_temp) in C:\Documents and Settings\user\My Documents\Visual Studio 2008\Projects\mySolution\DataAccessLayer\NHibernateDataProvider.cs:line 225 
     at InventoryDataClean.Controllers.ImportController.Edit(Int32 id, FormCollection formValues) in C:\Documents and Settings\user\My Documents\Visual Studio 2008\Projects\mySolution\InventoryDataClean\Controllers\ImportController.cs:line 101 
     at lambda_method(ExecutionScope , ControllerBase , Object[]) 
     at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) 
     at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) 
     at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) 
     at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassa.<InvokeActionMethodWithFilters>b__7() 
     at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) 
    InnerException: 

这里是我的物品映射 -

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataTransfer" namespace="DataTransfer"> 
    <class name="DataTransfer.items_temp, DataTransfer" table="items_temp"> 
    <id name="id" unsaved-value="any" > 
     <generator class="assigned"/> 
    </id> 
    <property name="assetid"/> 
    <property name="description"/> 
    <property name="caretaker"/> 
    <property name="category"/> 
    <property name="status" /> 
    <property name="vendor" /> 

    <many-to-one name="statusName" class="status" column="status" /> 
    </class> 
</hibernate-mapping> 

这里是我的状态映射 -

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataTransfer" namespace="DataTransfer"> 
    <class name="DataTransfer.status, DataTransfer" table="status"> 
    <id name="id" unsaved-value="0"> 
     <generator class="assigned"/> 
    </id> 
    <property name="name"/> 
    <property name="def"/> 

    </class> 
</hibernate-mapping> 

,这里是我的更新功能 -

public void UpdateItem_temp(items_temp item_temp) 
     { 
      ITransaction t = _session.BeginTransaction(); 
      try 
      { 
       _session.SaveOrUpdate(item_temp); 
       t.Commit(); 
      } 
      catch (Exception) 
      { 
       t.Rollback(); 
       throw; 
      } 
      finally 
      { 
       t.Dispose(); 
      } 
     } 

回答

11

您映射items_temp.status两次 - 一次为property,一次为many-to-one reference

<property name="status" /> 
<many-to-one name="statusName" class="status" column="status" /> 

如果你想这样做,你需要改变其中的一个列的名称。

+0

我认为通过更改名称statusName,我正确地做到了这一点。那我只好换个专栏了? – czuroski 2010-04-12 14:43:09

+0

否 - 它将使用属性名称和列名称 - 如果您确实有一个名为“status”的属性和一个名为“statusName”的属性,那么您需要有两列。我怀疑你有一个属性 - 所以你只需要M-to-1映射。 – 2010-04-12 14:55:14

+0

状态是项目表中保存与状态表相关的标识的字段。我不知道如何改变映射。 – czuroski 2010-04-12 14:56:09

0

这可能是由于NHibernate尝试将数据保存到数据库中的顺序。我怀疑这是因为它试图在外键键入被引用表之前在主表中设置外键ID。如果您发布映射和数据模式以及分配和保存属性的代码,将会有所帮助。

+0

我实际上不是增加一个新项目的外国表。这是一个静态表 - 它拥有不同的状态值和一个充当pk的整数ID。然后在项目表中,有一个状态字段与状态表相关。同时,我会发布我的映射。 谢谢 – czuroski 2010-04-12 14:09:27

+0

-1只有当您将FK列设置为不可空字符时才会发生。 – 2010-04-12 14:41:53

+0

大卫 - 好点,但不公平的投票我,因为他没有添加任何代码,当我添加我的答案。如果没有地图信息,我的答案是有效的,我确实要求czuroski为这个问题添加映射,所以我认为我的答复确实起了作用。 – 2010-04-12 15:17:13

1

我在尝试保存或更新实体之间存在不匹配映射和表格;特别是在列名拼写错误或列仅存在于两个位置中的一个位置时。

4

试试这个

many-to-one name="statusName" class="status" column="status" insert="false" update="false" 

或映射通过代码

ManyToOne<status>(x => x.statusName, map => {map.Column("status"); map.Update(false); map.Insert(false);}); 
+0

这实际上是我必须做的解决我非常类似的问题。我曾要求多对一和Id列的属性。 – 2012-07-05 18:13:10

2

我也有这个时候我错误地认为已经在我的Hibernate映射两个相同的列名。

东西一样傻的:

<property name="OrderId" column="order_id" /> 
<property name="OnlineOrderId" column="order_id" /> 
+0

如果这是一个要求,你可以添加_readonly_到其中的一个 – itsho 2017-12-27 21:40:21