2016-05-25 114 views
3

我正在使用Azure應用程序服務(移動應用程序)與SQLite一起使用脫機同步功能來開發應用程序。 我的數據對象模型是:Azure應用程序服務(移動應用程序)違反PRIMARY KEY約束

public class Customer : EntityData 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    //… 
    public DateTime DateCreated { get; set; } 
    public DateTime DateModified { get; set; } 
    public virtual IList<Card> Cards { get; set; } 
} 
public class Card : EntityData 
{ 
    public bool IsDisabled { get; set; } 
    public DateTime CreatedDate { get; set; } 
    public DateTime LastUsedDate { get; set; } 
} 

而且我的控制器代碼:

// GET tables/Customer 
    public IQueryable<Customer> GetAllCustomers() 
    { 
     return Query(); 
    } 

    // GET tables/Customer/48D68C86-6EA6-4C25-AA33-223FC9A27959 
    public SingleResult<Customer> GetCustomer(string id) 
    { 
     return Lookup(id); 
    } 

    // PATCH tables/Customers/48D68C86-6EA6-4C25-AA33-223FC9A27959 
    public Task<Customer> PatchCustomer(string id, Delta<Customer> patch) 
    { 
     return UpdateAsync(id, patch); 
    } 

    // POST tables/Customer 
    public async Task<IHttpActionResult> PostCustomer(Customer item) 
    { 
     Customer current = await InsertAsync(item); 
     return CreatedAtRoute("Tables", new { id = current.Id }, current); 
    } 

    // DELETE tables/Customer/48D68C86-6EA6-4C25-AA33-223FC9A27959 
    public Task DeleteCustomer(string id) 
    { 
     return DeleteAsync(id); 
    } 

我不太清楚這是怎麼幕後映射,但是從我的客戶,我呼籲:

await App.MobileService.SyncContext.PushAsync(); 
    await customerTable.PullAsync("customers", customerTable.CreateQuery()); 

當我執行數據的初始同步插入客戶時,所有工作都很好,但是,當我嘗試更新其中的任何一個時,我收到一個錯誤「操作因協作失敗nflict:'違反PRIMARY KEY約束'PK_dbo.Cards'。無法在對象'dbo.Cards'中插入重複鍵。重複的鍵值是(000000003414)。注意我沒有更改卡的詳細信息,只有客戶。 我看到這個職位:https://blogs.msdn.microsoft.com/azuremobile/2014/06/18/insertupdate-data-with-1n-relationship-using-net-backend-azure-mobile-services/ 但是,它似乎過於複雜,我不知道這是我之後...有誰知道發生了什麼?

+0

我懷疑你正在查看一個實體框架的問題,因爲Id是一個字符串 - 而不是一個int。在你的Customer對象中設置合適的CardId作爲字符串,然後通過ForeignKey註釋鏈接,也許? –

+0

移動服務需要Id是一個字符串,不知道爲什麼......當您提供移動服務後端時,我的控制器實現只是樣本解決方案提供的函數的重命名...... – Robin

+0

您是否已將斷點放在' PatchCustomer'?或者它再次擊中插入? – SWilko

回答

1

看來,Azure的應用服務(移動應用)是無法使用SQLite作爲當前時刻的中介時,處理外鍵。因此,唯一的方法是將表格作爲客戶端站點上的兩個獨立實體處理(您可以選擇將外鍵保留在服務端,但是這會導致嘗試使用外鍵查詢數據時出現問題) 。

2

有很多的,可能會錯誤可能的事情:也許你的客戶究竟是幹什麼的另一嵌件而非更新,這就是爲什麼你會得到一個409衝突異常。或者,插入成功的可能性較小,但響應丟失,因此客戶端將重試插入操作,並且會得到異常。

或者,它可能是問題是表之間的關係。爲了調試這個,首先你應該記錄你的傳出請求,這樣你就可以看到發生了什麼。如果您的客戶端正在發送插入而不是更新,則會在日誌中看到。請參閱Log outgoing requests in managed client (Xamarin, Windows)

然後,您可以將調試裝置連接到您的遠程服務或本地一個明白爲什麼實體框架驗證錯誤發生時運行。

順便說一句,如果你正在做離線同步,你也應該添加衝突處理代碼。下面是一個處理409(對於Insert Suceeds和響應丟失的情況)和412 precondition失敗(當兩個客戶端嘗試更新相同數據時)的示例:https://github.com/lindydonna/xamarin-forms-offline-sync/blob/master/XamarinFormsOffline/SyncHandler.cs#L23

+0

謝謝,我會嘗試您的調試建議,並在需要時向原始問題添加更多詳細信息。我知道衝突處理,但目前,這個「衝突」阻止除創建新記錄之外的任何東西,這會破壞同步對象... – Robin

+0

您的文章非常有幫助!謝謝! –

相關問題