2009-08-11 7 views
3

最近FluenNHibernateの使用を開始しました。私はSQLiteで単体テストを作成しようとしたときに奇妙な問題が発生しました。HQL to SQLiteデータベースでNHibernateの単純選択が機能しないのはなぜですか?

私はテスト用のメモリデータベースにSQLiteを使用しています。各テストメソッドに対して、データベースに存在するデータをクリアしています。例では:

var u = new User() { Name = "Piotr" }; 
_session.Save(u); 
_session.Clear(); 
var list = _session.CreateCriteria<User>().List(); 

このコードは正常に動作しますが、私は次の行に書くとき:

var list2 = _session.CreateQuery("FROM User").List(); 

私が取得:NHibernateのでgenereated

System.Data.SQLite.SQLiteException: SQLite error 
no such table: users 

SQLクエリで結構ですので、何が問題なの?

+0

リストを再度取得する前に、セッションをフラッシュしてみてください。 –

+0

申し訳ありません、エラーを表示します。あなたはデータベースのテーブル名Userとその名前をマッピングに混同しているかもしれません。マッピングの名前はテーブル名ではなく、テーブル名で使用する必要があります –

+0

2番目のクエリは実際にコードの次の行ですか? – anonymous

答えて

0

名前はおそらく?ユーザー - ユーザー。

2

あなたは、メモリ内SQLiteデータベースを使用していると述べました。 NHibernateは、2つのステートメントの間でデータベース接続を閉じることを決定している可能性があります。これにより、すべてのテーブルが失われてしまいます。

これを防ぐ1つの方法は、接続が閉じられるときに明示的に制御できるカスタムIConnectionProvider実装を作成することです。

は、ここで私は、プロジェクトでこれを処理するために使用したものです:あなたはまた、このクラスを指すように設定ファイルにconnection.providerオプションを設定する必要があると思い

public class InMemoryConnectionProvider : IConnectionProvider 
{ 
    private static readonly object syncObject = new object(); 
    private static SQLiteConnection connection; 

    #region IConnectionProvider Members 

    public void Configure(IDictionary<string, string> settings) 
    { 
    } 

    public void CloseConnection(IDbConnection conn) 
    { 
    } 

    public IDbConnection GetConnection() 
    { 
     CreateConnection(); 
     if (connection.State != ConnectionState.Open) 
     { 
      connection.Open(); 
     } 
     return connection; 
    } 

    public IDriver Driver 
    { 
     get { return new SQLite20Driver(); } 
    } 

    public void Dispose() 
    { 
    } 

    #endregion 

    public static void CreateConnection() 
    { 
     lock (syncObject) 
     { 
      if (connection == null) 
      { 
       var builder = new SQLiteConnectionStringBuilder 
           { 
            DataSource = ":memory:", 
            BinaryGUID = true, 
            DateTimeFormat = SQLiteDateFormats.ISO8601 
           }; 
       connection = new SQLiteConnection(builder.ConnectionString); 
       connection.Open(); 
      } 
     } 
    } 

    public static void DestroyConnection() 
    { 
     lock (syncObject) 
     { 
      if (connection != null) 
      { 
       connection.Dispose(); 
       connection = null; 
      } 
     } 
    } 
} 

テストでは、テストの開始時または設定方法のどちらかでスタティックInMemoryConnectionProvider.CreateConnection()メソッドを呼び出します。完了したら、InMemoryConnectionProvider.DestroyConnection()に接続して接続を終了します。 IConnectionProvider.CloseConnection()の実装はノーオペレーションなので、NHibernateはそれ自身で接続を閉じることができません。

+0

私はISessionを始めようとしていて、それを処分するのであれば、明らかに、ISession間にはデータベースが存在しないでしょうか? ISessionが作成される前にメモリ内のデータベースにスキーマをプッシュしようとすると、「*そのようなテーブルが見つかりません」、または* .hbmでスキーマを指定すると、その理由が説明されます。 xmlファイル、 "不明なデータベース"。 – apollodude217

+0

これはおそらく「そのようなテーブルがありません」エラーの場合です。 「未知のデータベース」は何かのように聞こえますが、 SQLiteはスキーマをサポートしていませんが、NHibernateの現在のバージョンではドットの代わりにアンダースコアを使用して偽装していると思います。、 "schema.table"ではなく "schema_table")。 古いバージョンを使用している場合、またはSQLiteダイアレクトが設定されていない場合、ATTACH DATABASEステートメントで接続された別のデータベースにアクセスしようとしていると解釈します。私はあなたがしていないと仮定します)。 –

0

インメモリデータベースを使用してSQLiteに問題がありました。接続/セッションが終了すると、データベースは破棄されます。ファイルの亜種を使用するほうがうまくいくようです。

また、データベースエンティティは、セッションファクトリセットアップの一部として作成する必要があります。セッションファクトリセットアップのようなものを試してみてください。

 // Create schema. 
     new SchemaExport(config).Create(false, true); 
関連する問題