在过去,我已经避免使用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语句的对象。
我可以看到有很多方法可以用来克服这个问题 - 任何人都有解决方案或他们认为可以解决这个问题的建议吗?
亲切的问候
艾伦。
答案 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或迁移脚本,这些脚本通常是多语句批处理。