报错信息:
Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded.
存储更新,插入或删除语句影响了意外的行数(0)。自加载实体以来,实体可能已被修改或删除。
原因:
线程1中被标记为删除的元素,在执行SaveChanges更新数据库的时候发现在数据库里已经不存在了(被另一个线程已经删除并物理更新了),这时候就会报错;
代码举例:
执行SaveStudent()方法时,会报错,前提:Student中要有数据(没有数据当然不存在这个问题。。。)
private static int mark = 0;
private static void SaveStudent()
{
Task.Factory.StartNew(() =>
{
SaveStudent2();
});
using (DBContext dbContext = new DBContext())
{
var ratios = dbContext.Student.ToList();
// 将所有元素标记为删除状态,但不更新数据库,
dbContext.Student.RemoveRange(ratios);
// 通知方法SaveStudent2执行
mark = 1;
// 等待方法SaveStudent2执行完毕,SaveStudent2方法会将要删除的元素删除并更新数据库
SpinWait.SpinUntil(() => mark == 2);
/* 此处会报错,因为当前方法将ratios中的元素标记为删除状态,但是要SaveChanges的时候,
* 发现数据库里已经没有这些元素了(因为在SaveStudent2方法中已经删除掉了)。
* 报错信息:
* Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded.
*/
dbContext.SaveChanges();
}
}
private static void SaveStudent2()
{
// 等到方法SaveStudent中已经将所有元素标记为删除状态
SpinWait.SpinUntil(() => mark == 1);
using (DBContext dbContext = new DBContext())
{
var ratios = dbContext.Student.ToList();
dbContext.Student.RemoveRange(ratios);
dbContext.SaveChanges();
// 删除所有元素后,更新数据库,然后通知SaveStudent继续执行
mark = 2;
}
}