如何使用SQLite.NET PCL运行一批SQL语句

时间:2014-06-12 03:17:25

标签: sqlite xamarin mvvmcross sqlite.net

在过去,我已经避免使用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语句的对象。

我可以看到有很多方法可以用来克服这个问题 - 任何人都有解决方案或他们认为可以解决这个问题的建议吗?

亲切的问候

艾伦。

2 个答案:

答案 0 :(得分: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 ();
    }

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

答案 1 :(得分:2)

我也遇到了这个问题。 I found a blog post that explains why.

以下是该帖子所说的内容,以防它丢失。

  

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

     

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

     

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