本地和远程保存数据(同步)

时间:2011-04-02 15:17:38

标签: windows-phone-7

输入数据时,最终需要远程保存在服务器上。如果当时没有数据连接,我确实希望应用程序正常工作,所以我需要在手机本地保存所有内容。然后,应用程序可以在获得连接时与服务器同步。

这引出了一个小问题。我习惯于在服务器上保存所有内容,然后使用服务器为其生成的id获取记录。如果没有连接,应用程序将本地保存到手机而不是服务器。当与服务器同步时,我没有看到电话知道何时记录回来本地记录与之关联的方法。没有足够的独特数据来解决这个问题。

处理此问题的最佳方法是什么?

我一直在考虑的一种方法是将记录的ID更改为GUID并让手机设置ID。这样,所有记录都将在本地具有id,并且在保存到服务器时,它仍应是唯一ID。

我想知道其他人一直在做什么,什么有效,有什么不经验。

2 个答案:

答案 0 :(得分:2)

这是我们几天前与朋友完成的第一个Windows Phone 7应用程序的完成方式。 它可能不是最好的解决方案,但“直到额外的重构它才能正常工作。 它是一个像mint.com这样的网络应用程序的应用程序,名为slamarica

如果我们有像保存交易这样的功能,我们首先检查我们是否有连接到互联网。

        // Check if application is in online or in offline mode 
        if (NetworkDetector.IsOnline)
        {
            // Save through REST API
            _transactionBl.AddTransaction(_currentTransaction);
        }
        else
        {
            // Save to phone database
            SaveTransactionToPhone(_currentTransaction);
        }

如果通过REST成功保存事务,它将使用事务对象进行响应,而不是将其保存到本地数据库。如果REST保存失败,我们将数据保存到本地数据库。

 private void OnTransactionSaveCompleted(bool isSuccessful, string message, Transaction savedTransaction)
    {
        MessageBox.Show(message);

        if(isSuccessful)
        {
            // save new transaction to local database
            DatabaseBl.Save(savedTransaction);

            // save to observable collection Transactions in MainViewModel
            App.ViewModel.Transactions.Add(App.ViewModel.TransactionToTransactionViewModel(savedTransaction));
            App.ViewModel.SortTransactionList();

            // Go back to Transaction List
            NavigationService.GoBack();
        }
        else
        {
            // if REST is failed save unsent transaction to Phone database
            SaveTransactionToPhone(_currentTransaction);

            // save to observable collection Transactions in MainViewModel
            App.ViewModel.Transactions.Add(App.ViewModel.TransactionToTransactionViewModel(_currentTransaction));
            App.ViewModel.SortTransactionList();
        }

    }

每个Transaction对象都有IsInSync属性。默认情况下,它设置为false,直到我们从REST API确认它已在服务器上保存成功。

用户可以刷新交易。用户可以单击“刷新”按钮从服务器获取新数据。我们在后台进行同步:

   private void RefreshTransactions(object sender, RoutedEventArgs e)
    {
        if (NetworkDetector.IsOnline)
        {
            var notSyncTransactions = DatabaseBl.GetData<Transaction>().Where(x => x.IsInSync == false).ToList();


            if(notSyncTransactions.Count > 0)
            {
                // we must Sync all transactions
                _isAllInSync = true;
                _transactionSyncCount = notSyncTransactions.Count;
                _transactionBl.AddTransactionCompleted += OnSyncTransactionCompleted;

                if (_progress == null)
                {
                    _progress = new ProgressIndicator();
                }

                foreach (var notSyncTransaction in notSyncTransactions)
                {
                    _transactionBl.AddTransaction(notSyncTransaction);
                }

                _progress.Show();
            }
            else
            {
                // just refresh transactions
                DoTransactionRefresh();
            }
        }
        else
        {
            MessageBox.Show(ApplicationStrings.NETWORK_OFFLINE);
        }
    }

 private void DoTransactionRefresh()
    {
        if (_progress == null)
        {
            _progress = new ProgressIndicator();
        }

        // after all data is sent do full reload
        App.ViewModel.LoadMore = true;
        App.ViewModel.ShowButton = false;
        ApplicationBl<Transaction>.GetDataLoadingCompleted += OnTransactionsRefreshCompleted;
        ApplicationBl<Transaction>.GetData(0, 10);

        _progress.Show();
    }

OnTransactionRefreshCompleted我们删除本地数据库中的所有事务数据并获取最新的10个事务。我们不需要所有数据,这样用户就可以同步数据。他总是可以通过在事务列表末尾添加更多数据来加载更多数据。它与Twitter应用程序类似。

 private void OnTransactionsRefreshCompleted(object entities)
    {
        if (entities is IList<Transaction>)
        {
            // save transactions
            var transactions = (IList<Transaction>)entities;
            DatabaseBl.TruncateTable<Transaction>();
            DatabaseBl.Save(transactions);
            ((MainViewModel) DataContext).Transactions.Clear();
            //reset offset
            _offset = 1;
            //update list with new transactions
            App.ViewModel.LoadDataForTransactions(transactions);

            App.ViewModel.LoadMore = false;
            App.ViewModel.ShowButton = true;
        }
        if (entities == null)
        {
            App.ViewModel.ShowButton = false;
            App.ViewModel.LoadMore = false;
        }

        // hide progress 
        _progress.Hide();

        // remove event handler
        ApplicationBl<Transaction>.GetDataLoadingCompleted -= OnTransactionsRefreshCompleted;
    }

答案 1 :(得分:1)

警告 - 我还没有尝试使用Windows Phone开发但是在遇到类似情况时我通常会使用GUID身份 - 例如,当我只有单向连接时创建记录到数据库 - 例如通过消息总线或队列。

它工作正常,虽然在记录大小方面有轻微的惩罚,并且还可能导致性能指数降低。我建议你试一试。