在实体框架中两次输入相同的记录

本文关键字:输入 两次 记录 框架 实体 | 更新日期: 2023-09-27 18:13:52

我正在审查一些EF代码,我想知道为什么它似乎是工作的。

代码很简单。我们有一个表,它需要一个查询来确定主键的适当字段。在运行查询和提交插入之间可能存在其他进程插入了新记录的情况,因此插入操作因违反主键而失败。(使用主键中的标识字段可以更好地处理这个问题,但我现在还不能重构这个问题。)为了解决这个问题,最初的程序员使用了一个循环:

MyRec myRec = new MyRec
{
    //.. set fields
};
bool isDone = false;
int retries = 0;
const int maxRetries = 8;
while (retries < maxRetries && !isDone)
{
    myRecseqno = getSeqno();
    try
    {
        myDbContext.myRecs.Add(myRec);
        myDbContext.SaveChanges();
        isDone = true;
    }
    catch
    {
        retries++;
    }
}

我不喜欢的一件事是它捕获每个异常,而不仅仅是一个主键冲突。(我不喜欢的另一件事是,这个函数在四个不同的类中有四个相同的副本)。但这不是我的问题。假设我将修复它。

让我烦恼的是,myRec被添加到集合多次,我不希望这工作。DbContext是一个工作单元,这意味着如果记录在第一次循环中被添加到集合中,那么在第二次循环中再次添加时,它仍然在集合中。

请记住,主键已经改变了,所以我认为这个集合将包含两条记录,在第二个循环之后,第一个记录使用原来的主键,第二个记录使用新的主键。

EF是否使用对象标识来识别何时将同一对象添加到集合中,两次?

在实体框架中两次输入相同的记录

建议您执行查询并在事务中插入,这将放置锁并阻止另一个进程插入。存储过程可以提供最佳性能,或者查看http://blogs.msdn.com/b/alexj/archive/2009/01/11/savechanges-false.aspx