与 Azure 移动应用程序的离线同步不起作用,数据库看起来是空的

Offline sync with Azure Mobile Apps not working, database looks empty

我正在尝试使用 Azure 移动应用程序实现离线数据库同步。当我使用远程版本(使用 MobileServiceClient.GetTable 而不是 MobileService.GetSyncTable)时,一切正常。但是,我无法让它与本地 SQLite 数据库一起使用。

DatabaseContext class 在 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();
    }
}

我的模型class:

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 returns 数据调用它。

有什么想法吗?

虽然您的 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; }
}

注意: 如果您将记录推送到服务器,它们将被填充。

我在自己这边进行了测试,发现我可以从服务器中提取记录并且在我的 sqlite 数据库中有记录。

await activitiesTable.PullAsync(null, activitiesTable.CreateQuery());

上面的代码会自动发送多个请求(单个请求的默认页面大小为 50)来拉取所有记录,然后它会执行以下 sql 语句来更新您的本地数据存储:

BEGIN TRANSACTION

INSERT OR 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 OR IGNORE INTO [__config] ([id]) VALUES (@p0)

UPDATE [__config] SET [value] = @p0 WHERE [id] = @p1

COMMIT TRANSACTION

详情请参考Debugging the Offline Cache

根据您的描述,您可以从您的服务器检索数据,但它无法更新您的本地 sqlite 数据库。我建议您可以在调用 PullAsync 时利用 fiddler 捕获网络跟踪并打开 sqlite 数据库来检查您的 table.

另外,如Using soft delete in Mobile Services所述如下:

When using the Offline data Sync for Mobile Services feature, the client SDK automatically queries for deleted records and removes them from the local database. Without soft delete enabled, you need to write additional code on the backend so that the client SDK knows which records to remove from the local store. Otherwise, the client local store and backend will be inconsistent with regard to these deleted records and the client method PurgeAsync() must be called to clear the local store.

注意:您在拨打PullAsync.

时需要查看记录中的deleted属性

此外,您可以利用移动应用程序下的“部署 > 快速入门”下载和运行 Xamarin.Forms 解决方案来缩小此问题的范围。详情请参考here. Also, you could refer to adrian hall's book about Chapter 3 - Data Access and Offline Sync.

问题出在 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/,此 class 无法正常工作,因为 "Id" 字段是驼峰式大小写。

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 class 可以使用远程表 (MobileClientService.GetTable<T>) 但不能使用同步表 (MobileClientService.GetSyncTable<T>)。