4

这看起来像是 Microsoft azure 移动客户端对 android 离线同步服务的限制。
在我的 xamarin 表单应用程序中,我有 40 个 azure 表可以与远程同步。每当特定请求(_abcTable.PullAsync)具有更多的数字记录(如 5K)时,PullAsync 就会返回异常,指出:执行 SQLite 命令时出错:'太多 SQL 变量'
拉取异步 URL 如下所示: https://abc-xyz.hds.host.com/AppHostMobile/tables/XXXXXXResponse ?$filter=(updatedAt ge datetimeoffset'2017-06-20T13:26:17.8200000%2B00:00' )&$orderby=updatedAt&$skip=0&$top=5000&ProjectId=2&__includeDeleted=true

但是在邮递员中,我可以看到相同的 Url 返回 5K 记录,并且在 iPhone 设备中也可以正常工作,但仅在 android 中失败。
从上面的 PullAsync 请求中,如果我将“top”参数值从 5000 更改为 500,它在 android 中可以正常工作,但需要更多时间。在不限制性能的情况下,我还有其他选择吗?

包版本:
Microsoft.Azure.Mobile.Client version="3.1.0"
Microsoft.Azure.Mobile.Client.SQLiteStore" version="3.1.0"

Microsoft.Bcl version="1.1.10"

Microsoft.Bcl.Build 版本="1.0.21" <br/> SQLite.Net.Core-PCL 版本="3.1.1"
SQLite.Net-PCL 版本="3.1.1" <br/> SQLitePCLRaw.bundle_green 版本="1.1.2"

SQLitePCLRaw.lib.e_sqlite3.android" version="1.1.2"

SQLitePCLRaw.provider.e_sqlite3.android" version="1.1.2"
如果我​​需要提供更多信息,请告诉我。谢谢

4

1 回答 1

0

执行 SQLite 命令时出错:'太多 SQL 变量

据我了解,您的 sqlite 可能会触及单个 SQL 语句中提到的最大主机参数数,如下所示:

主机参数是使用 sqlite3_bind_XXXX() 接口之一填充的 SQL 语句中的占位符。许多 SQL 程序员都熟悉使用问号(“?”)作为主机参数。SQLite 还支持以“:”、“$”或“@”开头的命名主机参数和“?123”形式的编号主机参数。

SQLite 语句中的每个主机参数都分配有一个编号。这些数字通常以 1 开头,并随着每个新参数增加 1。但是,当使用“?123”形式时,主机参数号是问号后面的数字。

SQLite 分配空间来保存从 1 到使用的最大主机参数号之间的所有主机参数。因此,包含主机参数(如 ?1000000000)的 SQL 语句将需要千兆字节的存储空间。这很容易使主机的资源不堪重负。为防止内存分配过多,主机参数编号的最大值为 SQLITE_MAX_VARIABLE_NUMBER,默认为 999

最大主机参数数可以在运行时使用 sqlite3_limit(db,SQLITE_LIMIT_VARIABLE_NUMBER,size) 接口降低。

参考了 Debugging the Offline CacheMobileServiceSQLiteStore并按如下方式初始化我的:

var store = new MobileServiceSQLiteStoreWithLogging("localstore.db");

我记录了调用时对 SQLite 存储执行的所有 SQL 命令pullasync。我发现通过以下请求从移动后端成功检索响应后:

https://{your-app-name}.azurewebsites.net/tables/TodoItem?$filter=((UserId%20eq%20null)%20and%20(updatedAt%20ge%20datetimeoffset'1970-01-01T00%3A00%3A00.0000000%2B00%3A00'))&$orderby=updatedAt&$skip=0&$top=50&__includeDeleted=true

Microsoft.Azure.Mobile.Client.SQLiteStore.dll将执行以下 sql 语句来更新相关的本地表:

开始交易

插入或忽略 [TodoItem] ([id]) 值 (@p0),(@p1),(@p2),(@p3),(@p4),(@p5),(@p6),(@ p7),(@p8),(@p9),(@p10),(@p11),(@p12),(@p13),(@p14),(@p15),(@p16),(@ p17),(@p18),(@p19),(@p20),(@p21),(@p22),(@p23),(@p24),(@p25),(@p26),(@ p27),(@p28),(@p29),(@p30),(@p31),(@p32),(@p33),(@p34),(@p35),(@p36),(@ p37),(@p38),(@p39),(@p40),(@p41),(@p42),(@p43),(@p44),(@p45),(@p46),(@ p47),(@p48),(@p49)

UPDATE [TodoItem] SET [Text] = @p0,[UserId] = @p1 WHERE [id] = @p2

UPDATE [TodoItem] SET [Text] = @p0,[UserId] = @p1 WHERE [id] = @p2

.

.

提交交易

据我了解,您可以尝试设置MaxPageSize为 999。此外,此限制来自 sqlite,更新处理由Microsoft.Azure.Mobile.Client.SQLiteStore. 目前,我还没有找到任何方法来覆盖Microsoft.Azure.Mobile.Client.SQLiteStore.

于 2017-06-29T08:49:27.940 回答