【问题标题】:SqLite in memory database : CREATE TABLE does not work?内存数据库中的 SqlLite:CREATE TABLE 不起作用?
【发布时间】:2013-07-02 20:52:42
【问题描述】:

在 SqlLite 文件数据库上使用此代码时,它工作正常。

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);
    }
}


但是在 SqlLite 'In Memory' 数据库 (Data Source=:memory:;Version=3;New=True;) 上运行此代码时,我得到了这个异常:

未处理的异常:System.Data.UpdateException:发生错误 在更新条目时。有关详细信息,请参阅内部异常。 ---> System.Data.SQLite.SQLiteException:SQL 逻辑错误或缺失 数据库没有这样的表:公司

请注意,这是使用 VS 2010、EF 4.4.0.0 和 sqlite-netFx40-setup-bundle-x86-2010-1.0.84.0 测试的


::: 更新 :::
正如 Simon Svensson 建议的那样,在任何其他命令之前打开连接确实可以解决问题: ctx.Connection.Open();

【问题讨论】:

  • EF 是否会关闭/重新打开 ExecuteStoreCommand 和 SaveChanges 之间的连接?这将重置内存数据库,因为连接是对它的唯一引用。
  • @Simon,你是对的。打开连接确实可以解决问题。这是 SqlLite 相关的问题吗?
  • 您的内存数据库在调用 SQLiteConnection.Open 时被实例化,因此您需要管理对该方法的调用。我已添加我的评论作为等待您接受的答案。 ;)

标签: c# sql entity-framework sqlite


【解决方案1】:

当您的 ORM 关闭您的连接并重新打开它时,就会发生这种情况。这会将 sqlite 内存数据库重置为其默认状态;即空。

除非您设置connection.release_mode = close(默认为after_transaction,否则NHibernate 也会发生同样的情况。

我不熟悉 Entity Framework,但我希望有类似的设置或使用 DataContext(IDbConnection) 构造函数,该构造函数记录为“如果您提供打开的连接,DataContext 将不会关闭它。”

同一文档还指出“在 System.Transactions 事务中,DataContext 不会打开或关闭连接以避免升级。”这可能是更清洁的解决方案。

使用一些反射器魔术表明它是 SQLiteConnection.Open 调用(通过 SQLite3.Open)sqlite3_open_interop(如果您使用的是 NuGet sqlite 包)。这表明每次调用 SQLiteConnection.Open 时都会得到一个新的空内存数据库。

【讨论】:

    猜你喜欢
    • 2017-01-30
    • 2021-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-03
    • 2017-06-15
    • 2023-03-12
    相关资源
    最近更新 更多