Подтвердить что ты не робот

IndexOutOfRangeException Глубоко в недрах NHibernate

У меня есть следующие отображения:

public class SecurityMap : ClassMap<Security>
    {
        public SecurityMap()
        {
            Table("Security");
            CompositeId().KeyProperty(k => k.Id, "SecurityId").KeyProperty(k => k.EndDate);
            Map(x => x.LastUpdateUser);
            References(x => x.Company).Columns("CompanyId", "EndDate");
            References(x => x.PrimaryListing).Columns("PrimaryListingId", "EndDate");
         }
    }

public class ListingMap : ClassMap<Listing>
    {
        public ListingMap()
        {
            Table("Listing");
            CompositeId().KeyProperty(k => k.Id, "ListingID").KeyProperty(k => k.EndDate);
            References(x => x.Security).Columns("SecurityId","EndDate");
        }
    }

 public class CompanyMap : ClassMap<Company>
    {
        public CompanyMap()
        {
            Table("Company");
            CompositeId().KeyProperty(k => k.Id, "CompanyID").KeyProperty(k => k.EndDate);
            HasMany(x => x.Securities).KeyColumns.Add("CompanyId", "EndDate");
        }       
    }

Когда я пытаюсь запустить этот тест:

[Test]
public void can_update_a_security()
{
    var repo = IoC.Resolve<ISecurityRepository>();
    int someSecurity = 1;
    using (var work = IoC.Resolve<IUnitOfWorkManager>().Current)
    {
        Security security = repo.Get(someSecurity);
        security.ShouldNotBeNull();
        security.LastUpdateUser = "Dirk Diggler" + DateTime.Now.Ticks;
        repo.Save(security);
        work.Commit();
    }
}

Я получаю следующую ошибку в глубине NHibernate:

Execute     System.IndexOutOfRangeException: неверный индекс 6 для этого SqlParameterCollection с графом = 6.     в System.Data.SqlClient.SqlParameterCollection.RangeCheck(Int32 индекс)     в System.Data.SqlClient.SqlParameterCollection.GetParameter(Int32 индекс)     в System.Data.Common.DbParameterCollection.System.Collections.IList.get_Item (Int32 индекс)     s:\NHibernate\NHibernate\SRC\NHibernate\Тип\DateTimeType.cs(65,0): в NHibernate.Type.DateTimeType.Set(IDbCommand st, значение объекта, индекс Int32)     s:\NHibernate\NHibernate\SRC\NHibernate\Тип\NullableType.cs(180,0): в NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd, значение объекта, индекс Int32)     s:\NHibernate\NHibernate\SRC\NHibernate\Тип\NullableType.cs(139,0): в NHibernate.Type.NullableType.NullSafeSet(IDbCommand st, значение объекта, индекс Int32, Сеанс ISessionImplementor)     s:\NHibernate\NHibernate\SRC\NHibernate\Тип\ComponentType.cs(213,0): в NHibernate.Type.ComponentType.NullSafeSet(IDbCommand st, значение объекта, начало Int32, Сеанс ISessionImplementor)     s:\NHibernate\NHibernate\SRC\NHibernate\стойкая бактерия \Entity\AbstractEntityPersister.cs(2393,0): в NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Объект id, Object [], Object rowId, Boolean [] includeProperty, Boolean [] [] includeColumns, таблица Int32, Заявление IDbCommand, Сеанс ISessionImplementor, Int32 индекс)     s:\NHibernate\NHibernate\SRC\NHibernate\стойкая бактерия \Entity\AbstractEntityPersister.cs(2754,0): в NHibernate.Persister.Entity.AbstractEntityPersister.Update(Объект id, Object [], Object [] oldFields, Object rowId, Boolean [] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, сеанс ISessionImplementor)     s:\NHibernate\NHibernate\SRC\NHibernate\стойкая бактерия \Entity\AbstractEntityPersister.cs(2666,0): в NHibernate.Persister.Entity.AbstractEntityPersister.UpdateOrInsert(Объект id, Object [], Object [] oldFields, Object rowId, Boolean [] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, сеанс ISessionImplementor)     s:\NHibernate\NHibernate\SRC\NHibernate\стойкая бактерия \Entity\AbstractEntityPersister.cs(2940,0): в NHibernate.Persister.Entity.AbstractEntityPersister.Update(Объект id, Object [], Int32 [] dirtyFields, Boolean hasDirtyCollection, Object [] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor сессия)     s:\NHibernate\NHibernate\SRC\NHibernate\Action\EntityUpdateAction.cs(78,0): в NHibernate.Action.EntityUpdateAction.Execute()     s:\NHibernate\NHibernate\SRC\NHibernate\Engine\ActionQueue.cs(130,0): в NHibernate.Engine.ActionQueue.Execute(IExecutable исполняемый файл)     s:\NHibernate\NHibernate\SRC\NHibernate\Engine\ActionQueue.cs(113,0): в NHibernate.Engine.ActionQueue.ExecuteActions(IList список)     s:\NHibernate\NHibernate\SRC\NHibernate\Engine\ActionQueue.cs(147,0): в NHibernate.Engine.ActionQueue.ExecuteActions()     s:\NHibernate\NHibernate\SRC\NHibernate\Event\Default\AbstractFlushingEventListener.cs(241,0): в NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource сессия)     s:\NHibernate\NHibernate\SRC\NHibernate\Event\Default\DefaultFlushEventListener.cs(19,0): в NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent мероприятие)     s:\NHibernate\NHibernate\SRC\NHibernate\Impl\SessionImpl.cs(1478,0): в NHibernate.Impl.SessionImpl.Flush()     s:\NHibernate\NHibernate\SRC\NHibernate\Транзакция\AdoTransaction.cs(187,0): в NHibernate.Transaction.AdoTransaction.Commit()     на lambda_method (ExecutionScope, ITransaction)

Теперь интересно, если я прокомментирую ссылку на компанию или PrimaryListing в SecurityMap, я не получаю ошибку. Кажется, не имеет значения, что я прокомментирую. Ошибка возникает только тогда, когда у меня есть оба.

Когда обновление действительно проходит через NHProf показывает мне это обновление:

UPDATE Security
SET    LastUpdateUser = '2010-02-19T08:09:24.00' /* @p0 */,
       CompanyId = 54199 /* @p1 */,
       EndDate = '9999-12-31T00:00:00.00' /* @p2 */
WHERE  SecurityId = 1 /* @p3 */
       AND EndDate = '9999-12-31T00:00:00.00' /* @p4 */

Я не уверен, почему он обновляет CompanyId и EndDate, но я подозреваю, что это связано.

У кого-нибудь есть идеи? Будет полезно оценить работу.

4b9b3361

Ответ 1

Да, это общая проблема, вы используете Column "EndDate" дважды в определении отображения (как для Компании, так и для PrimaryListing), и это недопустимо. Один из них должен пойти или иметь дополнительный столбец EndDate (по одному для каждой ассоциации)

проверить это тоже nHibernate 2.0 - отображение отношения составного идентификатора * и * много-к-одному приводит к "неверному индексу" ошибка

и http://devlicio.us/blogs/derik_whittaker/archive/2009/03/19/nhibernate-and-invalid-index-n-for-this-sqlparametercollection-with-count-n-error.aspx