Mvc中常见错误简单总结

一、修改实体类报错

存储区更新、插入或删除语句影响到了意外的行数(0)。实体在加载后可能被修改或删除。刷新 ObjectStateManager 项。
对于这个错误其实是由于表的主键没有赋值引起的,所以出现了“存储区更新、插入或删除语句影响到了意外的行数(0)”这句话。 如果是强类型view时如果不希望主键显示出来,建议可以这样做: @Html.HiddenFor(model => model.DispatchID)  就是设置一个隐藏控件来存储主键。如果不是强类型的view,则可以手动给你创建的实体对象添加主键的值。
二、一个实体对象不能由多个 IEntityChangeTracker 实例引用
在添加或者修改的时候不小心的话往往容易出现这个错误,那么这个错误是怎么产生的呢?
先给出解决方案,然后给出原理,仅攻大家参考:
解决方案:
你在对每个对象进行删除或者修改时都是先进行附加到上下文,然后修改状态,如下:
public virtual T Add(T model)
{
db.Set<T>().Add(model);
db.SaveChanges();
db.Entry<T>(model).State = EntityState.Detached;  //增加这句可以解决问题
return model;
}

原理:
在EF中有一个叫做对象管理容器(ObjectStateManager)的东东,如果你希望对某些对象进行增加、删除、修改,查询的操作,那么你首先需要把这些实体对象添加到这个对象管理容器中,
(查询出来的实体默认已经添加进去,不用手动添加了)。但是假如你把好几个对象都添加到了EF的对象管理容器中(ObjectStateManage)那么提交的时候,系统(EF)怎么知道你是增加、删除还是修改呢?
这时就需要另外一个东东出场了,它叫做DbEntityEntry(一个伪包装类)。这个伪包装类会自动把你放到对象管理容器中的对象包裹起来,这时你放进去的实体默认都放到一个自动产生的伪包装类中,
这个类还有一个很重要的属性就是对象的状态,是一个枚举类型的值。有Add、Deleted、Detached、Modified、Unchanged这样几个值,这几个值得意思就不用我讲解了吧,相信大家一看都懂。
这是db.savechanges()的时候EF就会根据实体和实体状体生成相应的sql语句,对数据库进行增删改查操作。

附加下图:

 

标签