我正在尝试使用Azure移动应用程序实现脱机数据库同步。当我使用远程版本(使用MobileServiceClient.GetTable而不是MobileService.GetSyncTable)时,一切正常。但是,我无法使用本地SQLite数据库。
DatabaseContext
类在Autofac容器中注册为单例。
public class DatabaseContext
{
private readonly MobileServiceClient _client;
private readonly MobileServiceSQLiteStore _store;
public DatabaseContext()
{
if (File.Exists(Constants.LocalDatabase))
{
File.Delete(Constants.LocalDatabase);
}
_client = new MobileServiceClient(Constants.ApiEndpoint);
_store = new MobileServiceSQLiteStore(Constants.LocalDatabaseName);
}
public async Task Initialize()
{
_store.DefineTable<Activities>();
await _client.SyncContext.InitializeAsync(_store);
await _client.SyncContext.PushAsync();
var activitiesTable = _client.GetSyncTable<Activities>();
await activitiesTable.PullAsync(null, activitiesTable.CreateQuery());
// DATA IS EMPTY
var data = await activitiesTable.CreateQuery().ToListAsync();
}
}
我的模特课:
public class Activities
{
public Guid Id { get; set; }
public string Name{ get; set; }
public DateTimeOffset? UpdatedAt { get; set; }
public DateTimeOffset? CreatedAt { get; set; }
public byte[] Version { get; set; }
}
当我在azure仪表板中查看我的流媒体日志时,我可以看到此请求:
GET /tables/Activities $skip=0&$top=50&__includeDeleted=true&$skip=0&$top=50&__includeDeleted=true&X-ARR-LOG-ID=19cd669b-df9a-41ee-b86e-9db766fc8e01 443 - 70.52.250.32 ZUMO/4.0+(lang=Managed;+os=Android;+os_version=6.0.1;+arch=Unix;+version=4.0.0.0) - 200 0 0 3228 1241 2160
使用Postman调用它返回数据。
有什么想法吗?
答案 0 :(得分:2)
虽然你的Activities
模型可能有用,但我会按如下方式定义我的模型:
public class Activities
{
public string Id { get; set; }
public string Name { get; set; }
[UpdatedAt]
public DateTimeOffset? UpdatedAt { get; set; }
[CreatedAt]
public DateTimeOffset? CreatedAt { get; set; }
[Version]
public byte[] Version { get; set; }
}
注意:数据库会更新createdAt
和updatedAt
和version
字段,如果您将记录推送到服务器,它们将会填充。
我在我身边测试过,发现我可以从服务器中提取记录,并且我的sqlite数据库中有记录。
await activitiesTable.PullAsync(null,activitiesTable.CreateQuery());
以上代码会自动发送多个请求(单个请求的默认页面大小为50)来提取所有记录,然后执行以下sql语句来更新本地数据存储:
BEGIN TRANSACTION
INSERT或IGNORE INTO [TodoItem]([id])VALUES(@ 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
COMMIT TRANSACTION
BEGIN TRANSACTION
INSERT或IGNORE INTO [__config]([id])VALUES(@ p0)
UPDATE [__config] SET [value] = @ p0 WHERE [id] = @ p1
COMMIT TRANSACTION
有关详细信息,请参阅Debugging the Offline Cache。
根据您的描述,您可以从服务器检索数据,但无法更新本地sqlite数据库。我建议您在调用PullAsync
时可以利用fiddler来捕获网络跟踪,并打开您的sqlite数据库来检查您的表。
此外,正如Using soft delete in Mobile Services所述:
使用Offline data Sync for Mobile Services功能时,客户端SDK会自动查询已删除的记录并将其从本地数据库中删除。如果未启用软删除,则需要在后端编写其他代码,以便客户端SDK知道要从本地存储中删除哪些记录。否则,客户端本地存储和后端将与这些已删除的记录不一致,并且必须调用客户端方法PurgeAsync()以清除本地存储。
注意:您需要在致电deleted
时查看记录中的PullAsync
媒体资源。
此外,您可以利用移动应用下的“DEPLOYMENT&gt;快速入门”下载并运行Xamarin.Forms解决方案来缩小此问题。有关详细信息,请参阅here。另外,你可以参考adrian hall的关于Chapter 3 - Data Access and Offline Sync的书。
答案 1 :(得分:2)
问题来自API方面。我能够使用Postman检索记录,但是id字段不是小写的。
[Key]
[TableColumn(TableColumnType.Id)]
public string Id { get; set; }
应该是:
[Key]
[TableColumn(TableColumnType.Id)]
public string id { get; set; }
非常令人沮丧的错误。
鉴于本教程:https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/chapter3/server/,由于&#34; Id&#34;这个类无法正常工作。田野是骆驼案。
namespace Chapter3.DataObjects
{
public class Example : EntityData
{
public string StringField { get; set; }
public int IntField { get; set; }
public double DoubleField { get; set; }
public DateTimeOffset DateTimeField { get; set; }
}
}
EntityData类将使用远程表(MobileClientService.GetTable<T>
),但不能使用同步表(MobileClientService.GetSyncTable<T>
)。