我正在尝试与通过Visual Studio中的模板生成的Xamarin应用程序进行脱机同步。在我添加DateTime字段之前,同步一直有效。 Xamarin代码或Sqlite似乎错误地解释了DateTime。这肯定是正确解释从服务器发送的DateTime值的问题,但如何解决?我是Xamarin和Sqlite的新手,所以我很困惑这个问题。该问题发生在
行await ClientServiceManager.ClientServiceManagerDefault.InspectionsTable.PullAsync("allInspections", _inspectionsTable.CreateQuery());
正在运行,但由于这已隐藏在类库中,因此我无法进行调试。
数据库中的数据看起来没问题(例如,参见突出显示的CreatedDate):
Fiddler报告以下json发送到移动应用程序:
同步后,如果您尝试使用select id, createddate from inspection
查询数据,则无法在Sqlite数据库中读取数据:
System.FormatException: String was not recognized as a valid DateTime.
如果我运行查询select id, cast(createddate as text) from inspection
,则为createddate显示的结果值为1525165956.457。
通过调用下面的PullAsync来触发同步:
public class ClientServiceManager
{
IMobileServiceSyncTable<InspectionItem> _inspectionItemsTable;
IMobileServiceSyncTable<Inspection> _inspectionsTable;
MobileServiceClient _client;
public MobileServiceClient CurrentClient
{
get { return _client; }
}
public static ClientServiceManager ClientServiceManagerDefault { get; set; } = new ClientServiceManager();
public IMobileServiceSyncTable<InspectionItem> InspectionItemsTable
{
get { return _inspectionItemsTable; }
}
public IMobileServiceSyncTable<Inspection> InspectionsTable
{
get { return _inspectionsTable; }
}
public ClientServiceManager()
{
_client = new MobileServiceClient(App.AzureMobileAppUrl)
{
SerializerSettings = new MobileServiceJsonSerializerSettings
{
CamelCasePropertyNames = true
}
};
var path = Path.Combine(MobileServiceClient.DefaultDatabasePath, "syncstore.db");
var store = new MobileServiceSQLiteStore(path);
store.DefineTable<Inspection>();
store.DefineTable<InspectionItem>();
_client.SyncContext.InitializeAsync(store, new MobileServiceSyncHandler());
_inspectionItemsTable = _client.GetSyncTable<InspectionItem>();
_inspectionsTable = _client.GetSyncTable<Inspection>();
}
public async Task<bool> SyncAsync()
{
try
{
Debug.WriteLine($"SyncAsync called. Need to sync {_client.SyncContext.PendingOperations} changes.");
//Pull server table changes to local tables.
await ClientServiceManager.ClientServiceManagerDefault.InspectionsTable.PullAsync("allInspections", _inspectionsTable.CreateQuery());
await ClientServiceManager.ClientServiceManagerDefault.InspectionItemsTable.PullAsync("allInspectionItems", _inspectionItemsTable.CreateQuery());
//Push all context changes to the server.
await _client.SyncContext.PushAsync();
}
catch (MobileServicePushFailedException exc)
{
Debug.WriteLine($"MobileServicePushFailedException occurred. Inner exception: {exc.InnerException}");
if (exc.PushResult == null)
{
Debug.WriteLine($"Unable to sync, which is alright since we have offline capabilities: {exc.Message}");
return false;
}
foreach (var error in exc.PushResult.Errors)
{
if (error.OperationKind == MobileServiceTableOperationKind.Update && error.Result != null)
{
//Update failed, reverting to server's copy.
await error.CancelAndUpdateItemAsync(error.Result);
}
else
{
// Discard local change.
await error.CancelAndDiscardItemAsync();
}
Debug.WriteLine($"Error executing sync operation. Item: {error.TableName} ({error.Item["id"]}). Operation discarded.");
}
}
catch (Exception ex)
{
Debug.WriteLine($"Unable to sync items: {ex.Message}");
return false;
}
return true;
}
}
此外,实体表基于此类,您可以在其中看到使用的数据类型:
using System;
#if SERVICE
using Microsoft.Azure.Mobile.Server.Tables;
#endif
namespace Abc.Base.Models
{
// The model class files are shared between the mobile and service projects.
public abstract class EntityData
#if SERVICE
: ITableData
#endif
{
#region ITableData Properties
public string Id { get; set; }
#if SERVICE
public DateTimeOffset? CreatedAt { get; set; } = DateTimeOffset.Now;
public DateTimeOffset? UpdatedAt { get; set; } = DateTimeOffset.Now;
public bool Deleted { get; set; }
public byte[] Version { get; set; }
#endif
#endregion
public DateTime? CreatedDate { get; set; }
public DateTime? UpdatedDate { get; set; }
}
}
答案 0 :(得分:0)
事实证明,pullasync工作正常。我一直使用Visual Studio插件&#34; SQLite / SQL Server Compact Toolbox检查SQLite表,并在尝试使用DateTimeOffset值呈现DateTime列时抛出错误。我为SQLite安装了数据库浏览器&#34; (http://sqlitebrowser.org/)并且在检查表时可以看到DateTimeOffset值,尽管它们被渲染为数字,而不是漂亮的日期和时间。