我正在使用 EF 开发 ASP.NET MVC 4.5 网站。我有代码检查数据库中的记录是否存在,如果不存在,则创建一个新记录。由于我的代码中存在问题(随后已修复),我在不到一秒的时间内调用了该代码两次。结果是创建了重复记录。这是我的代码:
Word wordToUpdate = context.Words.SingleOrDefault(w => w.Label == word);
if (wordToUpdate == null) // word doesn't exist yet so make a new one
{
Word w = new Word() {
// add new word stuff here
};
context.Words.Add(w);
}
else
{
// word already exists so just add stuff to existing entry
wordToUpdate.AnnotationGroups.Add(ag);
}
context.SaveChanges();
如果数据库中尚不存在该单词,则会添加两次。以下是重复记录的时间戳:
CreatedOn 2014-03-11 06:52:35.743 2014-03-11 06:52:50.637
我在查看数据库记录时单步执行了代码,并且在第一次执行期间添加了新记录,因此:
- 当数据库中有匹配记录时,为什么
context.Words.SingleOrDefault()
在第二次执行时返回 null? - 此表中不应存在重复记录。我如何改进我的代码以确保这种情况不可能发生?
编辑
让我添加一些我在上面代码片段开头使用断点进行调试时观察到的细节:
- 第一次调用时,一切都按预期工作 - 因为它是一个新单词
wordToUpdate
为 null,并且添加了一个新单词。 - 我在
context.SaveChanges()
处停止了代码并检查了数据库 - 出现了一个新行,其中添加了新单词 - 下一个调用(这是来自 Ajax.ActionLink 链接的 AJAX 调用)将使用相同的单词触发
wordToUpdate
返回 null,即使数据库已经包含该单词,因此会添加该单词的重复条目(我没有使用该单词作为主键,我宁愿在代码而不是尝试处理从数据库抛出的错误)- 当再次调用
context.SaveChanges
时,另一行将添加到数据库
所以我的问题是,由于这个调用来自同一个客户端,代码实际上是同步执行的吗?它在调试中逐步执行代码的方式似乎表明了这一点,但这就是我对 ASP.NET 的知识变得有点模糊的地方。
最佳答案
也许您的问题在于您使用的断言:w => w.Label == word
。
如果您正在比较对象,即使它们可能具有相同的内容, ==
只是比较它们是否具有相同的内存地址,这是默认实现。您应该重写 Word 类中的 Equals,以便行为比较键值或类似的内容。
关于asp.net - 为什么 "SingleOrDefault"在DB中有数据的情况下第二次执行时返回null?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22319118/