参考网址:https://www.cnblogs.com/zwjaaron/archive/2012/08/23/2652030.html
- 在MVC3中页使用Html.BeginForm()直接提交一个Entity进行更新,发现不行:也不会报错,就是数据没有实际更新掉!
- 查看底层的Update方法如下:
public int Update(T entity)
{
try
{
if (entity == null)
throw new ArgumentNullException("entity");
int flag = this._context.SaveChanges();
return flag;
}
catch (DbEntityValidationException dbEx)
{
var msg = string.Empty;
foreach (var validationErrors in dbEx.EntityValidationErrors)
foreach (var validationError in validationErrors.ValidationErrors)
msg += Environment.NewLine + string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
var fail = new Exception(msg, dbEx);
//Debug.WriteLine(fail.Message, fail);
throw fail;
}
}
3. 分析原因:
DbSet对象并没有提供相应的接口,为什么呢?因为EF相信自己的Self Tracking能力。也就是说,EF认为把一个entity从context中加载出来,做一些变更,然后直接SaveChanges就可以了,不需要特意提供一个Update方法。
但是这里有一个前提,就是“entity是从context中加载出来”。如果entity是新new出来的呢?比如在MVC里,entity 很可能是ModelBinder帮我们new出来的,context对它一无所知,直接SaveChanges显然不会有任何效果。
4.正确更新操作:
1>.根据Id(PK)查询出entity:一定要使用这个entity进行其它操作
2>.将更新内容赋值给查询出的entity
3>.不能用BindModel过来的entity直接进行传递给update()方法。
我个人出错的原因是
获取实体的时候数据是从缓存中取到的,没有实际去取导致操作的实体不是同一个导致更新无效。
public virtual Category GetCategoryById(int categoryId)
{
if (categoryId == 0)
return null;
string key = string.Format(CATEGORIES_BY_ID_KEY, categoryId);
return _cacheManager.Get(key, () => { return _categoryRepository.GetById(categoryId); });
}