2016-05-25 92 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

您的文章非常有帮助!谢谢! –

相关问题