重试实体框架 DbContext.SaveChanges 后双重插入密钥
本文关键字:插入 密钥 SaveChanges 实体 框架 DbContext 重试 | 更新日期: 2023-09-27 18:34:20
我在Azure上使用Entity Framework。对我的数据进行一些更改后,我调用DbContext.SaveChanges
。
在我的代码中,Messages
属于Conversations
。收到消息后,我将其添加到"消息"表中,并在"对话"表中创建其父级。如果我同时收到具有相同父级的两条消息,则有可能将具有相同主键的值双重插入到对话表中。
过程:
我将调用一些"如果不存在代码则插入对话":
if (this.Context.Conversations.SingleOrDefault(fc => fc.ConversationId == conversation.ConversationId) == null)
{
Context.Entry(conversation).State = EntityState.Added; //public DbEntityEntry Entry(object entity);
}
稍后我会打电话给this.Context.SaveChanges
我一直在阅读SQL Azure和实体框架连接错误处理,我很确定我想实现具有事务范围的重试策略。
如何在重试策略中包装
SaveChanges
一些想法:如何在重试策略中包装SaveChanges
。这会重试我之前运行的检查对话是否存在的代码吗?如何使我的重试策略重试非暂时性故障(如 PK 违规(?
如果重试策略是不可能的,那么在保存上下文时尽可能低地埋葬"创建或编辑(如果存在("逻辑的实体框架方法是什么?在这种特殊情况下,最好只调用存储过程吗?
这听起来更像是您想要的并发重试模式:
using (var context = new BloggingContext())
{
var blog = context.Blogs.Find(1);
blog.Name = "The New ADO.NET Blog";
bool saveFailed;
do
{
saveFailed = false;
try
{
context.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
saveFailed = true;
// Update the values of the entity that
//failed to save from the store
ex.Entries.Single().Reload();
}
} while (saveFailed);
}
参考:
http://msdn.microsoft.com/en-gb/data/jj592904.aspx
可悲的是 - 你没有。这不在 EF 可以开箱即用的范围内。重试逻辑显式仅处理暂时性连接问题。并且没有重试逻辑可以神奇地修复 PK 问题。EF 中也没有"更新插入"(更新或插入(逻辑。
你在这里只能靠自己 - 甚至问开发人员都没有意义,因为他们忙于 EF 7,甚至暂时放弃功能来实现这一点(如继承(。也许在一两年内,一旦 EF 具有更多功能并且在 v7 中稳定......但是不,目前什么都没有。
您必须在自己的应用程序逻辑中对此进行整理。