因为相同类型的其他实体已具有相同的主键值。在使用 “Attach” 方法或者将实体的状态设置为 “Unchanged” 或 “Modified” 时如果图形中的任何实体具有冲突键值,则可能会发生上述行为
这可能是因为某些实体是新的并且尚未接收数据库生成的键值(新实体)在此情况下,使用 “Add” 方法或者 “Added” 实体状态跟踪该图形,然后将非新实体的状态相应设置为 “Unchanged” 或 “Modified”。
其实这个错误就是EF开启事务时EF的上下文中已经存在了一条主键相同的数据,我个人遇到这个问题有多种情况:
情况一:
修改,循环修改一张表的同一条数据(如循环修改同一个物品的库存数量),这这种情况是应为第一次修改是没有清除上下文缓存
代码如下:
var Get_TAB =DB.Table.Where(p => p.ID== "001"&& .AsNoTracking().FirstOrDefault();
for(vari=0,i<5,i==){
Get_TAB .QTY=Get_TAB .QTY+1;//数量
DB.Table.Attach(Get_TAB );
DB.Entry< Table >(Get_TAB ).State = EntityState.Modified;
int c = DB.SaveChanges(); //提交
}
这里循环第一次不报错第二次就会报错
解决方案:
var Get_TAB =DB.Table.Where(p => p.ID== "001"&& .AsNoTracking().FirstOrDefault();//这里查询也要.AsNoTracking()加上这个清除上下文跟踪
for(vari=0,i<5,i==){
Get_TAB .QTY=Get_TAB .QTY+1;//数量
DB.Table.Attach(Get_TAB );
DB.Entry< Table >(Get_TAB ).State =EntityState.Modified;
int c = DB.SaveChanges(); //提交
DB.Entry< Table >(Get_TAB ).State = EntityState.Detached; //清除EF跟踪
}
情况二:
循环操作先添加一条数据,然后在去修改这条数据
代码如下:
for(vari=0,i<5,i==){
var Get_TAB =DB.Table.Where(p => p.ID== "001").AsNoTracking().FirstOrDefault();//这里查询也要.AsNoTracking()加
if(Get_TAB==null){
Table tb=ewn Table();
tb.QTY=1;//数量
DB.Table.ADD(tb);
int c = DB.SaveChanges(); //提交
}else{
Get_TAB.QTY=Get_TAB .QTY+1;//数量
DB.Table.Attach(Get_TAB );
DB.Entry< Table >(Get_TAB ).State = EntityState.Modified;
int c = DB.SaveChanges(); //提交
DB.Entry< Table >(Get_TAB ).State = EntityState.Detached; //清除EF跟踪
}
}
这里也会报错,尤其是新的EF或者新的实体
解决方案:
for(vari=0,i<5,i==){
var Get_TAB =DB.Table.Where(p => p.ID== "001").AsNoTracking().FirstOrDefault();//这里查询也要.AsNoTracking()加
if(Get_TAB==null){
var tb=ewn Table(){
tb.QTY=1,//数量
};
DB.Entry(tb).State = EntityState.Added;
int c = DB.SaveChanges();
DB.Entry(tb).State = EntityState.Detached;//清除添加时的EF上下问缓存
}else{
Get_TAB.QTY=Get_TAB .QTY+1;//数量
DB.Table.Attach(Get_TAB );
DB.Entry< Table >(Get_TAB ).State = EntityState.Modified;
int c = DB.SaveChanges();
DB.Entry< Table >(Get_TAB ).State = EntityState.Detached; //清除EF跟踪
}
}
暂时就写这两种吧