ArgumentOutOfRangeException:索引超出范围

时间:2009-03-01 19:07:03

标签: nhibernate fluent-nhibernate

每当我使用时,我都会遇到这种奇怪的ArgumentOutOfRangeException PersitenceSpecification类,用于验证具有的实体 引用值对象。

    public class CatalogItem : DomainEntity
    {
        internal virtual Manufacturer Manufacturer { get; private
set; }
        internal virtual String Name { get; private set; }

        protected CatalogItem()
        {}

        public CatalogItem(String name, String manufacturer)
        {
            Name = name;
            Manufacturer = new Manufacturer(manufacturer);
        }
    }

    public class CatalogItemMapping : ClassMap<CatalogItem>
    {
        public CatalogItemMapping()
        {
            Id(catalogItem => catalogItem.Id);

            Component<Manufacturer>(category => category.Manufacturer,
                                    m => m.Map(manufacturer =>
manufacturer.Name));

            Map(catalogItem => catalogItem.Name);
            Map(Reveal.Property<CatalogItem>("Price"));
        }
    }

    [TestFixture]
    public class When_verifying_the_class_mapping_of_a_catalog_item
        : NHibernateSpecification
    {
        [Test]
        public void Then_a_catalog_object_should_be_persistable()
        {
            new PersistenceSpecification<CatalogItem>(Session)
                .VerifyTheMappings();
        }
    }

    [TestFixture]
    public class NHibernateSpecification
        : Specification
    {
        protected ISession Session { get; private set; }

        protected override void Establish_context()
        {
            var configuration = new SQLiteConfiguration()
                .InMemory()
                .ShowSql()
                .ToProperties();

            var sessionSource = new SessionSource(configuration, new
RetailerPersistenceModel());
            Session = sessionSource.CreateSession();

            sessionSource.BuildSchema(Session);
            ProvideInitialData(Session);

            Session.Flush();
            Session.Clear();
        }

        protected override void Dispose_context()
        {
            Session.Dispose();
            Session = null;
        }

        protected virtual void ProvideInitialData(ISession session)
        {}
    }

这是我得到的错误:

  

测试用例   'Then_a_catalog_object_should_be_persistable'未执行:   System.ArgumentOutOfRangeException:   指数超出范围。一定是   非负和小于的大小   集合。参数名称:index           在System.ThrowHelper.ThrowArgumentOutOfRangeException   (ExceptionArgument参数,   ExceptionResource资源)           在System.ThrowHelper.ThrowArgumentOutOfRangeException()           在System.Collections.Generic.List 1.get_Item(Int32 index) at System.Data.SQLite.SQLiteParameterCollection.GetParameter(Int32 index) at System.Data.Common.DbParameterCollection.System.Collections.IList.get_Item (Int32 index) at NHibernate.Type.GuidType.Set(IDbCommand cmd, 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.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 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() d:\Builds\FluentNH\src\FluentNHibernate\Testing \PersistenceSpecification.cs(127,0): at FluentNHibernate.Testing.PersistenceSpecification 1.TransactionalSave   (Object propertyValue)           d:\构建\ FluentNH的\ src \ FluentNHibernate \测试   \ PersistenceSpecification.cs(105,0):   在   FluentNHibernate.Testing.PersistenceSpecification`1.VerifyTheMappings   ()           C:\来源\供应链\测试\ Retailer.IntegrationTests \映射   \ CatalogItemMappingSpecifications.cs(14,0):   在   SupplyChain.Retailer.IntegrationTests.Mappings.When_verifying_the_class_mapping_of_a_catalog_item.Then_a_catalog_object_should_be_persistable   ()

对不起,很长的帖子,但这个让我忙了几个 现在几小时。这可能不是由FNH引起的,因为我发现了这张JIRA票 NH本身提到了类似的东西:

http://forum.hibernate.org/viewtopic.php?p=2395409

我仍然希望我的代码中出错了:-)。任何 以为?

提前致谢

6 个答案:

答案 0 :(得分:15)

我找到了解决这个问题的方法,这个问题来自我自己 愚蠢起初。这一切都让我很清楚 从流畅的NH映射生成hbm文件。

<class name="CatalogItem" table="`CatalogItem`" xmlns="urn:nhibernate-
mapping-2.2" optimistic-lock="version">
    ...

    <property name="Name" length="100" type="String">
      <column name="Name" />
    </property>

    ...

    <component name="Manufacturer" insert="false" update="true">
      <property name="Name" length="100" type="String">
        <column name="Name" />
      </property>
    </component>
  </class>

请注意Name属性的列和列的列 制造商组件都映射到同一列。这就是为什么 这导致了ArgumentOutOfRangeException,因为有 比列名更多的参数。我解决了这个问题 明确指定组件映射的列名:

组件(catalogItem =&gt; catalogItem.Manufacturer,                       m =&gt; m.Map(manufacturer =&gt; manufacturer.Name, “制造商”));

另一个经验教训。

答案 1 :(得分:2)

就我而言,我使用Fluent NHibernate将两个属性映射到同一列。

答案 2 :(得分:0)

您的CatalogItem似乎没有Price属性,当您使用Reveal帮助时,这似乎很奇怪。

答案 3 :(得分:0)

是的,我删除了那个以减少一些噪音。我想我也忘了将它从映射中删除。在做了一些调查之后,我注意到它与制造商被映射为一个组件有关。当我使用普通的字符串而不是单独的类时,一切正常。

答案 4 :(得分:0)

在我的特定情况下,我在同一个.NET属性上添加了属性和ID(使用属性)。这导致了同样的错误。

答案 5 :(得分:0)

旧问题,但如果有人遇到与我相同的问题,可能会有助于知道this Fluent Nhibernate issue (ColumnPrefix only applied to first Component mapping inside a ComponentMap)可以提供相同的异常,因为并不总是应用列前缀。