Azure脱机同步

时间:2016-08-29 08:22:20

标签: c# azure azure-mobile-services

使用Azure应用服务与.net后端脱机同步。它工作得很好但是当我直接从服务器数据库中删除一行时,它在移动应用程序上单击刷新按钮后不会同步(更新)但如果我编辑任何名称属性,它会在单击刷新按钮后自动同步。据我所知,如果我删除服务器数据库中的任何行,它还应自动更新移动列表,因为它在编辑任何行后更新。 任何帮助!所以如果从数据库中删除一行然后刷新后显示新的更新数据库列表,我可以使其正常工作吗?

以下是toDoactivity.cs类

 public class ToDoActivity : Activity
{
    //Mobile Service Client reference
    private MobileServiceClient client;

    //Mobile Service sync table used to access data
    private IMobileServiceSyncTable<ToDoItem> toDoTable;

    //Adapter to map the items list to the view
    private ToDoItemAdapter adapter;

    //EditText containing the "New ToDo" text
    private EditText textNewToDo;

    const string applicationURL = @"https://my2doservice.azurewebsites.net";        

    const string localDbFilename = "local.db";

    protected override async void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Activity_To_Do);

        CurrentPlatform.Init();

        // Create the Mobile Service Client instance, using the provided
        // Mobile Service URL
        client = new MobileServiceClient(applicationURL);
        await InitLocalStoreAsync();

        // Get the Mobile Service sync table instance to use
        toDoTable = client.GetSyncTable<ToDoItem>();

        textNewToDo = FindViewById<EditText>(Resource.Id.textNewToDo);

        // Create an adapter to bind the items with the view
        adapter = new ToDoItemAdapter(this, Resource.Layout.Row_List_To_Do);
        var listViewToDo = FindViewById<ListView>(Resource.Id.listViewToDo);
        listViewToDo.Adapter = adapter;

        // Load the items from the Mobile Service
        OnRefreshItemsSelected();
    }

    public async Task InitLocalStoreAsync()
    {
        // new code to initialize the SQLite store
        string path = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), localDbFilename);

        if (!File.Exists(path)) {
            File.Create(path).Dispose();
        }

        var store = new MobileServiceSQLiteStore(path);
        store.DefineTable<ToDoItem>();

        // Uses the default conflict handler, which fails on conflict
        // To use a different conflict handler, pass a parameter to InitializeAsync. For more details, see http://go.microsoft.com/fwlink/?LinkId=521416
        await client.SyncContext.InitializeAsync(store);
    }

    //Initializes the activity menu
    public override bool OnCreateOptionsMenu(IMenu menu)
    {
        MenuInflater.Inflate(Resource.Menu.activity_main, menu);
        return true;
    }

    //Select an option from the menu
    public override bool OnOptionsItemSelected(IMenuItem item)
    {
        if (item.ItemId == Resource.Id.menu_refresh) {
            item.SetEnabled(false);

            OnRefreshItemsSelected();

            item.SetEnabled(true);
        }
        return true;
    }

    private async Task SyncAsync(bool pullData = false)
    {
        try {
            await client.SyncContext.PushAsync();

            if (pullData) {
                await toDoTable.PullAsync("allTodoItems", toDoTable.CreateQuery()); // query ID is used for incremental sync
            }
        }
        catch (Java.Net.MalformedURLException) {
            CreateAndShowDialog(new Exception("There was an error creating the Mobile Service. Verify the URL"), "Error");
        }
        catch (Exception e) {
            CreateAndShowDialog(e, "Error");
        }
    }

    // Called when the refresh menu option is selected
    private async void OnRefreshItemsSelected()
    {
        try
        {
            await SyncAsync(pullData: true); // get changes from the mobile service
            await RefreshItemsFromTableAsync(); // refresh view using local database
        }
        catch(Exception e)
        {
               CreateAndShowDialog(e, "Error");
        }
    }

    //Refresh the list with the items in the local database
    private async Task RefreshItemsFromTableAsync()
    {
        try {
            // Get the items that weren't marked as completed and add them in the adapter
            var list = await toDoTable.Where(item => item.Complete == false).ToListAsync();

            adapter.Clear();

            foreach (ToDoItem current in list)
                adapter.Add(current);

        }
        catch (Exception e) {
            CreateAndShowDialog(e, "Error");
        }
    }

    public async Task CheckItem(ToDoItem item)
    {
        if (client == null) {
            return;
        }

        // Set the item as completed and update it in the table
        item.Complete = true;
        try {
            await toDoTable.UpdateAsync(item); // update the new item in the local database
            await SyncAsync(); // send changes to the mobile service

            if (item.Complete)
                adapter.Remove(item);

        }
        catch (Exception e) {
            CreateAndShowDialog(e, "Error");
        }
    }

    [Java.Interop.Export()]
    public async void AddItem(View view)
    {
        if (client == null || string.IsNullOrWhiteSpace(textNewToDo.Text)) {
            return;
        }

        // Create a new item
        var item = new ToDoItem {
            Text = textNewToDo.Text,
            Complete = false
        };

        try {
            await toDoTable.InsertAsync(item); // insert the new item into the local database
            await SyncAsync(); // send changes to the mobile service

            if (!item.Complete) {
                adapter.Add(item);
            }
        }
        catch (Exception e) {
            CreateAndShowDialog(e, "Error");
        }

        textNewToDo.Text = "";
    }

    private void CreateAndShowDialog(Exception exception, String title)
    {
        CreateAndShowDialog(exception.Message, title);
    }

    private void CreateAndShowDialog(string message, string title)
    {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);

        builder.SetMessage(message);
        builder.SetTitle(title);
        builder.Create().Show();
    }
}

1 个答案:

答案 0 :(得分:2)

您可能需要在服务器上启用软删除。在服务器初始化代码中添加以下内容:

DomainManager = new EntityDomainManager<TodoItem>(context, Request, enableSoftDelete: true);

软删除允许您通知您的客户已删除记录。删除记录时,它只是标记为已删除。这允许其他客户端下载新状态并更新其脱机同步缓存。

要了解详情,请参阅30 Days of Zumo.v2 (Azure Mobile Apps): Day 19 – ASP.NET Table Controllers