Автономная синхронизация Azure Mobile. Невозможно удалить операцию из __operations - PullRequest
0 голосов
/ 04 сентября 2018

У меня огромная проблема, которую я пытался решить несколько дней. У меня есть сценарий, в котором я пытаюсь обработать конфликт вставки в моем проекте Xamarin. Проблема заключается в том, что запись в облачной базе данных не существует, поскольку возникла проблема с ограничением внешнего ключа, поэтому я нахожусь в сценарии, в котором обработчику конфликта синхронизации необходимо удалить локальную запись вместе с записью в __operations таблица в SQLite. Я пробовал все . Удалите с переопределением, установленным на «true», чтобы удалило локальную запись и все связанные операции. Не работает Я просто пытался принудительно удалить его, обращаясь к хранилищу SQL вручную:

var id = localItem[MobileServiceSystemColumns.Id];
var operationQuery = await store.ExecuteQueryAsync("__operations", $"SELECT * FROM __operations WHERE itemId = '{id}'", null).ConfigureAwait(false);
var syncOperation = operationQuery.FirstOrDefault();
var tableName = operation.Table.TableName;

await store.DeleteAsync(tableName, new List<string>(){ id.ToString() });

if (syncOperation != null)
{
    await store.DeleteAsync("__operations", new List<string>() { syncOperation["id"].ToString() }).ConfigureAwait(false);
}

Я могу запросить таблицу __operations и увидеть идентификатор элемента, который я хочу удалить. Метод DeleteAsync выполняется без исключения, но статус не возвращается, поэтому я понятия не имею, сработало ли это или нет. Когда я пытаюсь снова синхронизировать операцию упорно существует. Это кажется смешным . Как мне просто удалить операцию без синхронизации с веб-сервисом? Я собираюсь копнуть дальше и попытаться усилить это с помощью библиотеки SQLiteRaw, но я действительно надеюсь, что упустил что-то очевидное? Кто-нибудь может помочь? СПАСИБО!

1 Ответ

0 голосов
/ 05 сентября 2018

У вас должен быть подкласс класса Microsoft.WindowsAzure.MobileServices.Sync.MobileServiceSyncHandler, который переопределяет OnPushCompleteAsync () для обработки конфликтов и других ошибок. Давайте назовем класс SyncHandler:

public class SyncHandler : MobileServiceSyncHandler
{
    public override async Task OnPushCompleteAsync(MobileServicePushCompletionResult result)
    {
        foreach (var error in result.Errors)
        {
            await ResolveConflictAsync(error);
        }
        await base.OnPushCompleteAsync(result);
    }

    private static async Task ResolveConflictAsync(MobileServiceTableOperationError error)
    {
        Debug.WriteLine($"Resolve Conflict for Item: {error.Item} vs serverItem: {error.Result}");

        var serverItem = error.Result;
        var localItem = error.Item;

        if (Equals(serverItem, localItem))
        {
            // Items are the same, so ignore the conflict
            await error.CancelAndUpdateItemAsync(serverItem);
        }
        else // check server item and local item or the error for criteria you care about
        {
            // Cancels the table operation and discards the local instance of the item.
            await error.CancelAndDiscardItemAsync();
        }
    }
}

Включите экземпляр этого SyncHandler () при инициализации вашего MobileServiceClient:

        await MobileServiceClient.SyncContext.InitializeAsync(store, new SyncHandler()).ConfigureAwait(false);

Прочтите MobileServiceTableOperationError, чтобы увидеть другие конфликты, которые вы можете обработать, а также методы, позволяющие разрешить их.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...