输入数据时,最终需要远程保存在服务器上。如果当时没有数据连接,我确实希望应用程序正常工作,所以我需要在手机本地保存所有内容。然后,应用程序可以在获得连接时与服务器同步。
这引出了一个小问题。我习惯于在服务器上保存所有内容,然后使用服务器为其生成的id获取记录。如果没有连接,应用程序将本地保存到手机而不是服务器。当与服务器同步时,我没有看到电话知道何时记录回来本地记录与之关联的方法。没有足够的独特数据来解决这个问题。
处理此问题的最佳方法是什么?
我一直在考虑的一种方法是将记录的ID更改为GUID并让手机设置ID。这样,所有记录都将在本地具有id,并且在保存到服务器时,它仍应是唯一ID。
我想知道其他人一直在做什么,什么有效,有什么不经验。
答案 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身份 - 例如,当我只有单向连接时创建记录到数据库 - 例如通过消息总线或队列。
它工作正常,虽然在记录大小方面有轻微的惩罚,并且还可能导致性能指数降低。我建议你试一试。