9

在过去,我一直避免使用 ORM 并且总是手工制作参数化查询等。这在第一次开发应用程序时非常耗时且非常痛苦。最近我决定再看看 ORM,特别是 Sqlite.NET ORM。

我想使用 SQLite ORM 功能,但也能够运行一批本机 SQL 命令来预填充数据库。

我们正在使用 SqliteNetExtensions-MvvmCross dll 来启用一对多关系等,这一切看起来都很好。当我想用配置数据为数据库播种时,我的问题就出现了。我希望简单地提供一个包含一系列 sql 语句的 sql 文件,它将一个接一个地运行。

我已经从 GITHub 获取了 SQlite.NET 代码并运行了测试。然后,我扩展了具有简单 [Product] 表的 StringQueryTests 类来执行以下操作:-

     [Test]
    public void AlanTest()
    {
      StringBuilder sb = new StringBuilder(200);
      sb.Append(" DELETE FROM Product;");
      sb.Append(" INSERT INTO Product VALUES (1,\"Name1\",1,1);");
      sb.Append(" INSERT INTO Product VALUES (2,\"Name2\",2,3);");
      db.Execute(sb.ToString());
    }

当我运行它时,它不会抛出错误,实际上行为似乎是它只会运行第一个命令。如果我将 sb.ToString() 的内容粘贴到 sqlite 数据库查询窗口中,它将正常工作。

这是预期的行为吗?如果是这样,我该如何克服这个问题,以便我可以使用上述方法。如果可能的话,我真的不想创建对象来管理所有 SQL 语句。

我可以看到可以采用多种方法来解决这个问题 - 任何人都得到了他们认为可以解决这个问题的解决方法或建议?

亲切的问候

艾伦。

4

2 回答 2

3

你不能这样做:

    [Test]
    public void AlanTest()
    {
        var queries = new List<string> () 
        {
            " DELETE FROM Product",
            " INSERT INTO Product VALUES (1,\"Name1\",1,1)",
            " INSERT INTO Product VALUES (2,\"Name2\",2,3)"
        };

        db.BeginTransaction ();
        queries.ForEach (query => db.Execute (query));
        db.Commit ();
    }

你真的不需要事务,只需要更快的执行/检查点回滚......

于 2015-01-09T04:16:33.397 回答
3

我也遇到了这个问题。我找到了一篇解释原因的博客文章。

这是帖子中的内容,以防丢失。

所有代码 [in sqlite-net] 正确检查结果代码并相应地抛出异常。

虽然我没有在这里发布所有相关代码,但我确实对其进行了审查,并且这种行为的真正起源在其他地方 - 在本机 sqlite3.dll sqlite3_prepare_v2 方法中。这是文档的相关部分:

这些例程只编译 zSql 中的第一条语句,因此 *pzTail 指向未编译的内容。由于 sqlite-net 不对未编译的尾部执行任何操作,因此实际上只执行命令中的第一条语句。其余部分被默默忽略。在大多数情况下,您在使用 sqlite-net 时不会注意到这一点。您将使用其微 ORM 层或执行单个语句。想到的唯一常见例外是尝试执行通常是多语句批处理的 DDL 或迁移脚本。

于 2015-10-20T02:52:19.200 回答