Я следую руководству по началу работы с NHibernate: «Ваше первое приложение на основе NHibernate». Я нахожусь в точке, где я создаю объект Product, а затем использую Session.get (), чтобы доказать, что я могу прочитать объект.
Он отлично работает с SQL Server Ce, но я получаю исключение при попытке использовать DB2. (Версия SQL Server Ce работает - то есть. Есть некоторые незначительные изменения между версиями, такими как int вместо GUID для идентификатора.)
У меня большой опыт работы с базами данных Hibernate и SQL. Это мой первый опыт работы с NHibernate и DB2. (Исходя из мира Java). Буду признателен за любые предложения, особенно от (очевидно, немногих) людей, которые используют NHibernate в DB2.
Роб
Полное исключение:
Тестовый метод examples.DB2.NHibernateExamples.Can_add_new_product threw
исключение: 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_. Прекращено как Disconti4_1_0_ ИЗ ПРОДУКТА
product0_ WHERE product0_.Id =?] ---> System.IndexOutOfRangeException:
Неверный индекс 0 для этой коллекции DB2ParameterCollection с числом = 0.
Это происходит в вызове Get (...) в следующем коде:
[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);
}
Похоже, исключение указывает на то, что параметр Id не передается в запрос 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>
Я работаю в Visual Studio 2010 Premium на Windows 7. Я использую DB2 Express-C 9.7.4.