C# Azure应用程序服务(移动应用程序)违反主键约束
我正在使用Azure应用程序服务(移动应用程序)开发一个应用程序,该应用程序使用SQLite的脱机同步功能。 我的数据对象模型是:C# Azure应用程序服务(移动应用程序)违反主键约束,c#,sqlite,azure,azure-mobile-services,C#,Sqlite,Azure,Azure Mobile Services,我正在使用Azure应用程序服务(移动应用程序)开发一个应用程序,该应用程序使用SQLite的脱机同步功能。 我的数据对象模型是: public class Customer : EntityData { public string FirstName { get; set; } public string LastName { get; set; } //… public DateTime DateCreated { get; set; } public
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; }
}
当我执行数据的初始同步以插入客户时,一切正常。但是,当我尝试更新任何客户时,我收到一个错误“操作因冲突而失败:'违反主键约束'PK_dbo.Cards'。无法在对象'dbo.Cards'中插入重复键。重复键值为(00000000 3414).注意:我没有更改卡的详细信息,只更改了客户。
我看过这个帖子:
然而,它似乎过于复杂,我不确定这是否是我所追求的……有人知道发生了什么吗?有很多可能会出错的事情:可能您的客户端实际上正在进行另一次插入而不是更新,这就是为什么会出现409冲突异常。或者,不太可能的是,插入成功,但响应丢失,因此客户端将重试插入,并将获得异常 或者,问题可能是表之间的关系。若要调试此问题,首先应记录传出请求,以便查看发生的情况。如果客户端发送的是插入而不是更新,则会在日志中看到。请参阅 然后,您可以将调试器附加到远程服务或本地运行的服务,以查看发生实体框架验证错误的原因
顺便说一句,如果你正在进行脱机同步,你还应该添加冲突处理代码。下面的示例处理409(对于插入成功且响应丢失的情况)和412预处理失败(当两个客户端尝试更新相同数据时):。似乎Azure应用程序服务(移动应用程序)当前使用SQLite作为中介时无法处理外键。因此,唯一的方法是将表作为客户端站点上的两个独立实体处理(您可以选择将外键保留在服务端,但这将导致使用外键查询数据时出现问题).我怀疑您正在关注实体框架问题,因为Id是字符串,而不是int。请在客户对象中将相应的CardId设置为字符串,然后通过ForeignKey注释链接,也许?移动服务要求Id为字符串,但不确定为什么……我的控制器实现只是对函数的重命名当您提供移动服务后端时,随示例解决方案一起提供…您是否在
PatchCustomer
上设置了断点?或者它是否再次点击insert?我已在PatchCustomer上设置了断点,并且正确点击了该断点。然后它将调用UpdateAsync并返回如上所述的错误…谢谢,我将尝试您的调试su如果需要的话,我知道冲突的处理方法,但目前,除了创建新记录之外,这一“冲突”阻止了任何违背同步目标的事情……您的帖子非常有用!谢谢!
// 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());