我有以下课程。
public class AzureMobileDataContext : IAsyncInitialization
{
private static readonly Lazy<AzureMobileDataContext> lazy =
new Lazy<AzureMobileDataContext> (() =>
new AzureMobileDataContext(
new MobileServiceClient(
"http://myservice.azure-mobile.net/",
"123456789ABCDEFGHIJKLMNOP")));
public static AzureMobileDataContext Instance { get { return lazy.Value; } }
public Task Initialization { get; private set; }
public IMobileServiceClient Context { get; private set; }
private Object lockObj = new Object ();
private static MobileServiceSQLiteStore store;
public AzureMobileDataContext (IMobileServiceClient context)
{
Context = context;
Initialization = Init ();
Initialization.ContinueWith (async (antecedent) => {
await Context.SyncContext.InitializeAsync (store, new MobileServiceSyncHandler ());
});
}
private Task Init ()
{
return Task.Run (() => {
lock (lockObj) {
if (!Context.SyncContext.IsInitialized) {
try {
store = new MobileServiceSQLiteStore ("mysqlite.db3");
store.DefineTable<Post> ();
store.DefineTable<PostPhotoUrl> ();
store.DefineTable<User> ();
store.DefineTable<Club> ();
store.DefineTable<District> ();
} catch (Exception ex) {
Debug.WriteLine ("Init: {0}", ex.Message);
}
}
}
});
}
public async Task<IMobileServiceSyncTable<TEntity>> GetTableAsync<TEntity> ()
{
await Initialization;
return Context.GetSyncTable<TEntity> ();
}
public async Task PushAsync ()
{
try {
await Initialization;
await Context.SyncContext.PushAsync ();
} catch (MobileServiceInvalidOperationException invalidOperationEx) {
Debug.WriteLine (invalidOperationEx.Message);
} catch (MobileServicePushFailedException pushFailedException) {
Debug.WriteLine (pushFailedException.Message);
}
}
public async Task PullAsync<TEntity> (IMobileServiceTableQuery<TEntity> query)
{
try {
await Initialization;
IMobileServiceSyncTable<TEntity> entityTable = await GetTableAsync<TEntity> ();
await entityTable.PullAsync (typeof(TEntity).ToString (), query); // Never returns, no exception is caught or thrown.
await entityTable.PurgeAsync ();
} catch (MobileServiceInvalidOperationException preconditionFailedEx) {
Debug.WriteLine (preconditionFailedEx.Message);
} catch (Exception ex) {
Debug.WriteLine (ex.Message);
}
}
public async Task SyncAsync<TEntity> ()
{
await PushAsync ();
IMobileServiceSyncTable<TEntity> syncTable = await GetTableAsync<TEntity> ();
await PullAsync (syncTable.CreateQuery ());
}
}
我在BaseRepository中使用这个单例,我有5个不同实体存储库的基类。
public abstract class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected AzureMobileDataContext MobileServiceContext { get { return AzureMobileDataContext.Instance; } }
protected virtual Task PushAsync ()
{
return MobileServiceContext.PushAsync ();
}
protected virtual Task PullAsync (IMobileServiceTableQuery<TEntity> query)
{
return MobileServiceContext.PullAsync (query);
}
public virtual async Task<DataObjectResponse<IEnumerable<TEntity>>> FindAsync (Expression<Func<TEntity, bool>> predicate)
{
IMobileServiceSyncTable<TEntity> syncTable = await MobileServiceContext.GetTableAsync<TEntity> ();
await PullAsync (syncTable.CreateQuery ());
IEnumerable<TEntity> entities = await syncTable.Where (predicate).ToEnumerableAsync ();
return new DataObjectResponse<IEnumerable<TEntity>> (entities);
}
}
用户存储库。
public class UsersAzureRepository : BaseRepository<User>, IUsersRepository
{
public UsersAzureRepository ()
{
}
public async Task<DataObjectResponse<User>> FindByIdAsync (string entityId)
{
DataObjectResponse<IEnumerable<User>> users = await FindAsync (p => p.Id == entityId);
return new DataObjectResponse<User>(users.Data.FirstOrDefault ());
}
}
包含GetUserById
方法的DataService Facade类。
public async Task<UserModel> GetUserById (string userId)
{
DataObjectResponse<User> users = await UsersRepository.FindByIdAsync (userId);
UserModel userModel = Mapper.Map<User, UserModel> (users.Data);
return userModel;
}
用户查看模型方法。
public async Task<UserModel> GetUsersAsync() // testing purposes
{
UserModel user = await _dataService.GetUserById("032beb3b-1cbf-4a0d-809c-a25c71139c55");
if (user != null) {
Debug.WriteLine ("User loaded: {0}", user.Id);
}
return user;
}
从iOS UIViewController调用。
public async override void ViewDidLoad ()
{
base.ViewDidLoad ();
UserModel user = await ViewModel.GetUsersAsync ();
}
AzureMobileDataContext
更多地作为IMobileServiceClient
上下文操作的线程安全包装器,确保不会有多个线程尝试初始化数据库(直接将它用于{{时我有一个例外) 1}}之前)。
我不太确定问题出在哪里。我怀疑包装器不是最好的解决方案,欢迎提出任何建议。
调试BaseRepository<T>
方法的其他任何方法?
[编辑]
本地SQLite数据库同步来自远程服务的表数据,但仍然不会返回调用。