2011-04-02 88 views
3

輸入數據時,最終需要遠程保存在服務器上。如果當時沒有數據連接,我確實希望應用程序能夠正常工作,所以我需要在手機上保存所有內容。應用程序可以在獲取連接時與服務器同步。在本地和遠程保存數據(同步)

這帶來了一個小問題。我習慣於將所有內容保存在服務器上,然後使用服務器爲它們生成的id獲取記錄。如果沒有連接,應用程序將本地保存到手機中,但不保存在服務器上。在與服務器同步時,我看不到手機知道記錄何時與本地記錄關聯的記錄。沒有足夠的獨特數據來解決這個問題。

處理這個問題的最佳方法是什麼?

我一直在想的一種方法是將記錄的ID更改爲GUID並讓手機設置ID。這樣,所有記錄在本地都會有一個ID,當保存到服務器時,它應該仍然是一個唯一的ID。

我想知道其他人一直在做什麼,什麼是有效的,什麼不是來自於經驗。

回答

1

警告 - 我還沒有與Windows Phone的開發試過,但使用GUID的身份是什麼,當面對類似情況下,我通常做的 - 例如,創建記錄時,我只有一個單向連接到數據庫 - 如通過消息總線或隊列。

它工作正常,儘管在記錄大小上有一個小小的懲罰,並且也可能導致較少的性能指標。我建議你給它一個鏡頭。

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

    } 

每個事務對象都有IsInSync屬性。它默認設置爲false,直到我們從REST API獲得確認,它已在服務器上保存成功。

用戶有能力刷新交易。用戶可以點擊按鈕Refresh來從服務器獲取新數據。我們做同步在這樣的背景:

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; 
    } 
相關問題