3

このコードを SqLite ファイル データベースで使用すると、問題なく動作します。

using (var ctx = new Test2010Entities())
{
    string s = "CREATE TABLE 'Company' ([Id] integer PRIMARY KEY AUTOINCREMENT NOT NULL, varchar(50) NOT NULL);";

    ctx.ExecuteStoreCommand(s);

    ctx.Companies.AddObject(new Company { Code = "_1" });
    ctx.Companies.AddObject(new Company { Code = "_2" });

    ctx.SaveChanges();

    foreach (var c in ctx.Companies.ToList())
    {
        Console.WriteLine(c.Code);
    }
}


しかし、SqLite 'In Memory' データベース ( Data Source=:memory:;Version=3;New=True; ) でこのコードを実行すると、次の例外が発生します。

未処理の例外: System.Data.UpdateException: エントリの更新中にエラーが発生しました。詳細については、内部例外を参照してください。---> System.Data.SQLite.SQLiteException: SQL ロジック エラーまたは見つからないデータベースにそのようなテーブルはありません: Company

これは、VS 2010、EF 4.4.0.0、および sqlite-netFx40-setup-bundle-x86-2010-1.0.84.0 でテストされていることに注意してください。


::: 更新 :::
Simon Svensson が示唆したように、他のコマンドよりも先に接続を開くと、次のようにトリックが実行されます。

4

1 に答える 1

8

これは、ORM が接続を閉じ、再度開くときに発生します。これにより、sqlite インメモリ データベースがデフォルトの状態にリセットされます。つまり、空です。

設定しない限り、NHibernate でも同じことが起こりますconnection.release_mode = close(デフォルトはafter_transaction.

私はEntity Frameworkに精通していませんが、同様の設定またはDataContext(IDbConnection)「開いている接続を提供すると、DataContextはそれを閉じない」と文書化されているコンストラクターを使用することを期待しています。

同じドキュメントには、「System.Transactions トランザクションでは、DataContext は昇格を避けるために接続を開いたり閉じたりすることはありません」とも記載されています。これはよりクリーンなソリューションになる可能性があります。

Reflector マジックを使用すると、(SQLite3.Open 経由で) sqlite3_open_interop を呼び出すのは SQLiteConnection.Open であることがわかります (NuGet sqlite パッケージを使用している場合)。これは、SQLiteConnection.Open を呼び出すたびに、新しい空のインメモリ データベースを取得することを示しています。

于 2013-07-05T09:15:48.583 に答える