Azure App Services(移动应用程序)违反PRIMARY KEY约束

时间:2016-05-25 14:08:21

标签: c# sqlite azure azure-mobile-services

我正在使用Azure App Services(移动应用程序)使用SQLite的离线同步功能开发应用程序。 我的数据对象模型是:

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());

当我执行初始数据同步以插入客户时,一切正常,但是,当我尝试更新其中任何一个时,我收到错误“操作因冲突而失败:'违反PRIMARY KEY约束'PK_dbo 。牌'。无法在对象'dbo.Cards'中插入重复键。重复键值为(000000003414)。注意我没有更改卡的详细信息,只有客户。 我看过这篇文章:https://blogs.msdn.microsoft.com/azuremobile/2014/06/18/insertupdate-data-with-1n-relationship-using-net-backend-azure-mobile-services/ 然而,它似乎过于复杂,我不确定它是否是我所追求的......有谁知道发生了什么?

2 个答案:

答案 0 :(得分:2)

有很多可能出现问题的事情:也许您的客户端实际上是在进行另一次插入而不是更新,这就是为什么您会遇到409冲突异常的原因。或者,不太可能,插入成功但响应丢失,因此客户端将重试插入,并将获得异常。

或者,可能是问题是表之间的关系。要对此进行调试,首先应记录传出请求,以便查看正在进行的操作。如果您的客户端发送插入而不是更新,您将在日志中看到。请参阅Log outgoing requests in managed client (Xamarin, Windows)

然后,您可以将调试器附加到远程服务或本地运行的调试程序,以查看实体框架验证错误发生的原因。

顺便说一句,如果你正在进行离线同步,你还应该添加冲突处理代码。这是一个处理409的示例(对于Insert suceeds和响应丢失的情况)和412前提条件失败(当两个客户端尝试更新相同的数据时):https://github.com/lindydonna/xamarin-forms-offline-sync/blob/master/XamarinFormsOffline/SyncHandler.cs#L23

答案 1 :(得分:1)

在当前使用SQLite作为中介时,Azure App Services(移动应用程序)似乎无法处理外键。因此,唯一的方法是在客户端站点上将表处理为2个单独的实体(您可以选择将外键保留在服务端,但这会导致尝试使用外键查询数据时出现问题)