2017-08-31 53 views
0

我正在開發一個應用程序,現在我卡在我的UWP應用程序的註冊頁面。如何在客戶端使用SQLite存儲在SQL Azure數據庫中存儲枚舉?

所以我爲我的應用程序創建了一個後端,後端的一些變量是枚舉,例如我有一個Named Personal類,它有一個像這樣的枚舉變量public Gender性別{get; set;} thats和enum,無論何時我將我的表中的該變量轉換爲sql Azure中的一個int值。

這沒有問題,但我的主要問題在我的客戶。 我下面Adrian Hall Book,所以我有以下類在我的客戶:

public class Personal : TableData 
{ 
    [Required] 
    [StringLength(50)] 
    [JsonProperty(PropertyName = "name")] 
    public string Name { get; set; } 
    [Required] 
    [StringLength(50)] 
    [JsonProperty(PropertyName = "dadlastname")] 
    public string DadLastName { get; set; } 
    [Required] 
    [StringLength(50)] 
    [JsonProperty(PropertyName = "momlastname")] 
    public string MomLastName { get; set; } 
    [Required] 
    [StringLength(50)] 
    [JsonProperty(PropertyName = "email")] 
    public string Email { get; set; } 
    [Required] 
    [JsonProperty(PropertyName = "sex")] 
    public Gender Sex { get; set; }//ENUM TYPE 
    [Required] 
    [Column(TypeName = "date")] 
    [JsonProperty(PropertyName = "birthdate")] 
    public DateTime? BirthDate { get; set; } 

    public override bool Equals(object obj) 
    { 
     return Equals<Personal>(obj, this); 
    } 

    public override int GetHashCode() 
    { 
     return Id.GetHashCode(); 
    } 
} 

,你可以看到這是我的枚舉:

public enum Gender : Int32 
{ 
    [Display(Name = "EnumGenderMale")] 
    Male = 0, 
    [Display(Name = "EnumGenderFemale")] 
    Female = 1 
} 

我知道默認枚舉從繼承的Int32,但我試圖做這個工作,所以每次我初始化我的後備存儲,它創建我的sqllite.db,但根據我的日誌記錄的枚舉類型創建爲類型[TEXT],所以每當我嘗試在我的後端寫入它會引發HTTPStatusCode: 500內部服務器錯誤,它不寫我的sqlazure數據庫上的任何東西。

我猜它的主要問題,因爲我使用枚舉它有一個最佳實踐,以便在客戶端使用枚舉並能夠在我的後端寫入?

我的錯誤是在我的pushasync方法拋出這是我對我的同步類的類:

public async Task SyncOfflineCacheAsync() 
    { 
     await InitializeAsync(); 

     try 
     { 
      await client.SyncContext.PushAsync(); 
     } 
     catch (MobileServicePushFailedException ex) 
     { 
      if(ex.PushResult != null) 
      { 
       foreach (var error in ex.PushResult.Errors) 
       { 
        var objString = error.Item.ToString(); 
        await ResolveAnyConflictAsync(error, objString); 
       } 
      } 
     } 
     catch(Exception ex) 
     { 
      Debug.WriteLine($"Database corrupted, purging database: {ex.Message}"); 
      //purge database 
     } 

     //Pull each sync table 
     var accountTable = await GetSyncTableAsync<Account>(); 
     await accountTable.PullAsync(); 

     var personalTable = await GetSyncTableAsync<Personal>(); 
     await personalTable.PullAsync(); 

     var laborTable = await GetSyncTableAsync<Labor>(); 
     await laborTable.PullAsync(); 

     var subscriptionTable = await GetSyncTableAsync<Subscription>(); 
     await subscriptionTable.PullAsync(); 
    } 

public async Task InitializeAsync() 
    { 
     //Short circuit to database if its already initialized. 
     if(client.SyncContext.IsInitialized) 
     { 
      Debug.WriteLine($"InitializedAsync: Short Circuit"); 
      return; 
     } 

     //create a reference to the local sqlLite store. 
     Debug.WriteLine("InitializeAsync: Initializing store"); 
     var store = new MobileServiceSQLiteStoreWithLogging("ceneam.db", true, true); 

     //Define Database Schema    
     store.DefineTable<Account>(); 
     store.DefineTable<Personal>(); 
     store.DefineTable<Labor>(); 
     store.DefineTable<Subscription>(); 

     //Actually create the store and update the schema. 
     Debug.WriteLine("InitializeAsync: Initializing SyncContext"); 
     await client.SyncContext.InitializeAsync(store); 

     //Do the sync 
     Debug.WriteLine("InitializeAsync: Syncing Ceneam Offline Cache"); 
     await SyncOfflineCacheAsync(); 
    } 

public static async Task ResolveAnyConflictAsync(MobileServiceTableOperationError error, string objString) 
    { 
     switch (GetModelErrorType(objString)) 
     { 
      case "Account": 
       { 
        await ResolvePushConflictAsync<Account>(error); 
        break; 
       } 
      case "Personal": 
       { 
        await ResolvePushConflictAsync<Personal>(error); 
        break; 
       } 
      case "Labor": 
       { 
        await ResolvePushConflictAsync<Labor>(error); 
        break; 
       } 
      case "Subscription": 
       { 
        await ResolvePushConflictAsync<Subscription>(error); 
        break; 
       } 
     } 
    } 

    static async Task ResolvePushConflictAsync<T>(MobileServiceTableOperationError error) where T : TableData 
    { 
     Debug.WriteLine($"Resolve conflict for {error.Item}"); 
     var serverItem = error.Result.ToObject<T>(); 
     var localItem = error.Item.ToObject<T>(); 

     // Note that you need to implement the public override Equals(TableModel item) 
     // method in the Model for this to work 
     if(serverItem.Equals(localItem)) 
     { 
      //Items are the same, so ignore the conflict 
      await error.CancelAndDiscardItemAsync(); 
      return; 
     } 

     //Client wins 
     localItem.Version = serverItem.Version; 
     await error.UpdateOperationAsync(JObject.FromObject(localItem)); 

     //Server wins 
     //await error.CancelAndDiscardItemAsync(); 
    } 

所以這個類顯示,在當時我在申請我自己的那本書的版本阿德里安·霍爾書籍教。在阿德里安大廳的例子,只使用布爾和文本我能夠同步我的數據庫沒有錯誤我猜它失敗,因爲我使用枚舉,有人可以指出我的方向正確如何使用Azure移動時處理枚舉應用程序,因爲即使我擺脫脫機支持(sqlLite店)它一直失敗,我不斷收到錯誤代碼500.

回答

1

根據op的描述,我檢查了我的身邊這個問題,並從服務器項目Download and run the client project快速啓動刀片在天藍色的門戶。它可以工作在我的本地端如預期,你可以參考我的測試如下:

服務器型號:

public class ToDoItem : EntityData 
{ 
    public string Text { get; set; } 
    public bool Complete { get; set; } 
    public Gender Sex { get; set; } 
} 

public enum Gender 
{ 
    [Display(Name = "EnumGenderMale")] 
    Male = 0, 
    [Display(Name = "EnumGenderFemale")] 
    Female = 1 
} 

客戶端模式:

public class TodoItem 
{ 
    public string Id { get; set; } 

    [JsonProperty(PropertyName = "text")] 
    public string Text { get; set; } 

    [JsonProperty(PropertyName = "sex")] 
    public Gender Sex { get; set; } 
} 

public enum Gender 
{ 
    [Display(Name = "EnumGenderMale")] 
    Male = 0, 
    [Display(Name = "EnumGenderFemale")] 
    Female = 1 
} 

訪問數據通過瀏覽器:

enter image description here

客戶端應用程序:

enter image description here

添加一個新的記錄,檢查本地的SQLite店:

enter image description here

呼叫await App.MobileService.SyncContext.PushAsync();,使用Fiddler捕獲網絡跟蹤如下:

enter image description here

can somebody point my in the right direction on how to treat enums when using Azure Mobile Apps, because even If I get rid of Offline support (sqlLite store) it keeps failing and I keep getting error code 500.

配置config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;Startup.MobileApp.cs您的移動應用程序項目的文件,以獲取詳細的錯誤信息。另外,您可以參考here來調試您的移動應用程序後端。

+0

謝謝你,我發現我的錯誤,謝謝你的答案的最後部分,事實證明,我有我的setdomainmanager方法公開。只要我將其更改爲私有,我就停止收到此錯誤:「找到與請求匹配的多個操作」。我能夠發佈在我的數據庫上。你爲我節省了大量的時間,我在猜測廢話! –