2011-09-26 105 views
2

我正在关注NHibernate入门教程:“您的第一个基于NHibernate的应用程序”。我正在创建一个Product对象,然后使用Session.get()来证明我可以读取对象。NHibernate在DB2 session.get()抛出System.IndexOutOfRangeException

它适用于SQL Server Ce,但在尝试使用DB2时遇到异常。 (SQL Server Ce版本的工作原理 - 就是像int这样的版本之间有一些小的变化,而不是ID的GUID)。

我对Hibernate和SQL数据库非常有经验。这是我第一次使用NHibernate和DB2。 (来自Java世界)。我会很感激任何建议,尤其是那些在DB2上使用NHibernate的人(显然很少)。

罗布

完整的例外是

试验方法Examples.DB2.NHibernateExamples.Can_add_new_product抛出 例外:NHibernate.Exceptions.GenericADOException:无法加载 实体:[Examples.DB2。 Domain.Product#1] [SQL:SELECT product0_.Id as Id1_0_,product0_.Name as Name1_0_,product0_.Category as Category1_0_,product0_.Discontinued as Disconti4_1_0_ FROM Product product0_ WHERE product0_.Id =?] ---> System.IndexOutOf RangeException: Count = 0的此DB2ParameterCollection的索引0无效。

这是在得到以下代码(...)调用发生的事情:

[TestInitialize] 
    public void TestInitialize() 
    { 
     TestFixtureSetup(); 
     SetupContext(); 
    } 


    [TestMethod] 
    public void Can_add_new_product() 
    { 
     var product = new Product { Id = 1, Name = "Apple", Category = "Fruits"}; 

     using (ISession session = _sessionFactory.OpenSession()) 
     { 
      using (ITransaction transaction = session.BeginTransaction()) 
      { 
       session.Save(product); 
       transaction.Commit(); 
      } 
     } 

     using (ISession session = _sessionFactory.OpenSession()) 
     { 
      //var query = session.CreateQuery("from Product"); 
      //var products = query.List<Product>(); 
      //Assert.AreEqual(1, products.Count); 

      var fromDb = session.Get<Product>(product.Id); 
      Assert.IsNotNull(fromDb); 
      Assert.AreNotSame(product, fromDb); 
      Assert.AreEqual(product.Name, fromDb.Name); 
      Assert.AreEqual(product.Category, fromDb.Category); 
     } 
    } 

    private void TestFixtureSetup() 
    { 
     _configuration = new Configuration(); 
     _configuration.Configure(); 
     _configuration.AddAssembly(typeof (Domain.Product).Assembly); 
     _sessionFactory = _configuration.BuildSessionFactory(); 
    } 

    private void SetupContext() 
    { 
     new SchemaExport(_configuration).Execute(true, true, false); 
    } 

的例外似乎表明,该标识放慢参数没有被传递到DB2查询。如果我在Get()之前取消注释这三行,它会正常工作,因为该行已被缓存,并且Get()实际上不会进入数据库。

这里是Product.cs的定义:

using System; 

namespace Examples.DB2.Domain 
{ 
    class Product 
    { 
     public virtual int Id { get; set; } 
     public virtual string Name { get; set; } 
     public virtual string Category { get; set; } 
     public virtual bool Discontinued { get; set; } 
    } 
} 

这里是Product.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
        assembly="Examples.DB2" 
        namespace="Examples.DB2.Domain"> 

    <class name="Product"> 
    <id name="Id"> 
     <generator class="native" /> 
    </id> 
    <property name="Name" /> 
    <property name="Category" /> 
    <property name="Discontinued" type="YesNo"/> 
    </class> 

</hibernate-mapping> 

这里是hibernate.cfg.xml中:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> 
    <session-factory> 
    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property> 

    <property name="dialect">NHibernate.Dialect.DB2Dialect</property> 
    <property name="connection.driver_class">NHibernate.Driver.DB2Driver</property> 
    <property name="connection.connection_string">Database=SAMPLE; UID=DEV; PWD=password</property> 

    <property name="show_sql">true</property> 
    </session-factory> 
</hibernate-configuration> 

我正在使用Windows 7上的Visual Studio 2010 Premium。我正在使用DB2 Express-C 9.7.4。

回答

1

好吧,

我找到了答案......不完全确定的解决方案的又,但在NHibernate最终释放前,他们加入到AdoNet\AbstractBatcher.cs打电话叫RemoveUnusedCommandParameters。此过程调用Driver.RemoveUnusedCommandParameters

我现在的解决方案只是将这个调用注释掉,让函数不做任何事情。

我会把它与nhusers小组一起看看是否有更好的长期解决方案。

感谢

DBL

+0

感谢您的答复。我没有马上看到它,因为它没有发送到我的电子邮件。必须在我的个人资料上工作。 –

相关问题