4

初めてNHibernateを使用しています。OleDBを使用してSQLBaseデータベースに接続するように設定しました。私はいくつかのクラスを設定し、それが機能するかどうかを確認するために最初の短いテストを試しました。

これは私のテストです:

[TestClass]
public class Hibernate
{
    private ISessionFactory _sessionFactory;
    private Configuration _config;

    [TestInitialize]
    public void InitTest()
    {
        _config = new Configuration();
        _config.Configure();
        _config.AddAssembly(typeof(Coil).Assembly);
        _sessionFactory = _config.BuildSessionFactory();
    }


    [TestMethod]
    public void TestMethod1()
    {
        using (var session = _sessionFactory.OpenSession())
        {
            Int32 coilid = 12189;
            Coil coil = session.Get<Coil>(coilid);
            Assert.AreEqual(coil.CoilNumber, "6FEB13");
        }
    }
}

そして、これがマッピングの関連部分です:

<class name="Coil" table="COIL">
<id name="ID" column="COILID" type="integer">
  <generator class="hilo">
    <param name="table">DEFTAB</param>
    <param name="column">WERT1</param>
    <param name="max_lo">10</param>
    <param name="where">TBCODE='LFDNR' AND CODE='WGID'</param>
  </generator>
</id>
<property name="CoilNumber" column="COILNR" type="string" />
</class>

簡単なテストを実行しようとすると、GenericADOExceptionが発生します:エンティティを読み込めませんでした。[SQL:SELECT ... WHEREcoil0_.COILID =?] ---> System.Data.OleDb.OleDbException:プログラムバインド変数が無効です。

SELECT ... WHERE Coil0_.COILID = 12189をSQLbaseクライアントにコピーすると、クエリはエラーなしで成功します。問題は、どういうわけかNHibernateが私のid変数をクエリに入れず、代わりに単に?を入れることです。そこの。

テストで間違った構文を使用しているだけですか、それとも構成に問題がありますか?

最後に、それが役立つ場合は、休止状態の構成ファイル:

  <session-factory>
<property  name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.GenericDialect</property>
<property name="connection.driver_class">NHibernate.Driver.OleDbDriver</property>
<property name="connection.connection_string">Provider=SQLBASEOLEDB.1;Password=XXX;User ID=XXX;Data Source=XXX</property>
<property name="show_sql">true</property>

繰り返しますが、SQL出力は問題ありませんが、NHibernateが関数に使用するIDをSQLクエリに入れない理由がわかりません。

編集:COILIDは、データベーステーブルの通常のINTEGERであり、Coilクラスのintです。

Edit2:これがスタックトレースです

System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr)
System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams, Object& executeResult)
System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult)
System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object& executeResult)
System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
System.Data.OleDb.OleDbCommand.System.Data.IDbCommand.ExecuteReader()
NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd)
NHibernate.Loader.Loader.GetResultSet(IDbCommand st, Boolean autoDiscoverTypes, Boolean callable, RowSelection selection, ISessionImplementor session)
NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, String optionalEntityName, Object optionalIdentifier, IEntityPersister persister)
NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, String optionalEntityName, Object optionalIdentifier, IEntityPersister persister)
NHibernate.Loader.Entity.AbstractEntityLoader.Load(ISessionImplementor session, Object id, Object optionalObject, Object optionalId)
NHibernate.Loader.Entity.AbstractEntityLoader.Load(Object id, Object optionalObject, ISessionImplementor session)
NHibernate.Persister.Entity.AbstractEntityPersister.Load(Object id, Object optionalObject, LockMode lockMode, ISessionImplementor session)
NHibernate.Event.Default.DefaultLoadEventListener.LoadFromDatasource(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
NHibernate.Event.Default.DefaultLoadEventListener.DoLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
NHibernate.Event.Default.DefaultLoadEventListener.Load(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
NHibernate.Event.Default.DefaultLoadEventListener.ProxyOrLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent event, LoadType loadType)
NHibernate.Impl.SessionImpl.FireLoad(LoadEvent event, LoadType loadType)
NHibernate.Impl.SessionImpl.Get(String entityName, Object id)
NHibernate.Impl.SessionImpl.Get(Type entityClass, Object id)
NHibernate.Impl.SessionImpl.Get[T](Object id)
Tests.Hibernate.TestMethod1() in "D:\Hibernate.cs": Zeile 36

Coilテーブルのテーブル作成構文は次のとおりです。

CREATE TABLE COIL (
  COILID INTEGER NOT NULL, 
  COILNR VARCHAR(50), 
);

Edit5:すべてのエントリのクエリは機能しますが、テーブルから特定のエントリを取得したい場合はすぐに?再びエラー:(

var allCoils = session.CreateCriteria<Coil>().List<Coil>();
Coil datCoil = allCoils.First<Coil>(coil => coil.CoilNumber == "6FEB13");
Assert.AreEqual(datCoil.CoilNumber, "6FEB13");

このテストは少なくとも成功しています

Edit6:問題は、nhibernateが次のようにSQLを準備することのようです。

DEBUG NHibernate.SQL - SELECT coil0_.COILID as COILID1_0_, coil0_.COILNR as COILNR1_0_ FROM COIL coil0_ WHERE coil0_.COILID=?;p0 = 12189

しかし、SQLbaseは次のような準備された文字列を必要としています

WHERE coil0_.COILID = :0
\
12189
/

nhibernateがバインド変数をSQLに変換する方法を変更するにはどうすればよいですか?

4

1 に答える 1

0

SQLBase 用の独自のドライバーとダイアレクト (それぞれ OleDbDriver と GenericDialect から) を作成することで、この問題を解決できました。NHibernate で SQLBase を使用するために他の誰かがコードを必要とする場合は、コードを投稿できます。

于 2013-03-22T10:26:32.240 に答える