Azure 移动离线同步:无法从 __operations 中删除操作
Azure Mobile Offline Sync: Cannot delete an operation from __operations
我遇到了一个大问题,几天来我一直在努力解决这个问题。我有一个场景,我试图在我的 Xamarin 项目中处理插入冲突。问题是云数据库中的记录不存在,因为外键约束存在问题,所以我处于同步冲突处理程序需要删除本地记录以及 __operations table 在 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 table 并且可以看到我要删除的项目的 ID。 DeleteAsync 方法无一例外地运行,但没有返回任何状态,所以我不知道这是否有效。当我尝试再次同步时,该操作顽固地存在。这似乎荒谬。如何在不与 Web 服务同步的情况下只删除操作?我打算进一步深入挖掘并尝试通过使用 SQLiteRaw 库来更加努力地强制它,但我真的很希望我遗漏了一些明显的东西?谁能帮忙?谢谢!
您需要 Microsoft.WindowsAzure.MobileServices.Sync.MobileServiceSyncHandler class 的子class,它会覆盖 OnPushCompleteAsync() 以处理冲突和其他错误。让我们调用 class 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();
}
}
}
在初始化 MobileServiceClient 时包括此 SyncHandler() 的一个实例:
await MobileServiceClient.SyncContext.InitializeAsync(store, new SyncHandler()).ConfigureAwait(false);
阅读 MobileServiceTableOperationError
以了解您可以处理的其他冲突及其解决冲突的方法。
我遇到了一个大问题,几天来我一直在努力解决这个问题。我有一个场景,我试图在我的 Xamarin 项目中处理插入冲突。问题是云数据库中的记录不存在,因为外键约束存在问题,所以我处于同步冲突处理程序需要删除本地记录以及 __operations table 在 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 table 并且可以看到我要删除的项目的 ID。 DeleteAsync 方法无一例外地运行,但没有返回任何状态,所以我不知道这是否有效。当我尝试再次同步时,该操作顽固地存在。这似乎荒谬。如何在不与 Web 服务同步的情况下只删除操作?我打算进一步深入挖掘并尝试通过使用 SQLiteRaw 库来更加努力地强制它,但我真的很希望我遗漏了一些明显的东西?谁能帮忙?谢谢!
您需要 Microsoft.WindowsAzure.MobileServices.Sync.MobileServiceSyncHandler class 的子class,它会覆盖 OnPushCompleteAsync() 以处理冲突和其他错误。让我们调用 class 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();
}
}
}
在初始化 MobileServiceClient 时包括此 SyncHandler() 的一个实例:
await MobileServiceClient.SyncContext.InitializeAsync(store, new SyncHandler()).ConfigureAwait(false);
阅读 MobileServiceTableOperationError
以了解您可以处理的其他冲突及其解决冲突的方法。