关于Entity Framework中的Attached报错的完美解决方案终极版
2015-07-16 11:42
423 查看
之前发表过一篇文章题为《关于Entity Framework中的Attached报错的完美解决方案》,那篇文章确实能解决单个实体在进行更新、删除时Attached的报错,注意我这里说的单个实体,指的是要更新或删除的实体不包含其它实体(比如导航属性就包含其它实体),也就是简单POCO对象;但如果不是呢?那么那篇文章里的方法在一定程度上不起作用了,仍会报错,我开始也想不明白,明明通过IsAttached函数判断要更新的实体并未Attached,但进行Attaching时但仍然报错说有相同Key,开始还以为是MS的BUG,后经过多次反复调试发现,报错是对的,因为他报的错并不是我当前要更新的实体,而是该实体中关联的实体,代码与演示报错如下:(仅是演示代码)
针对这个报错,我在想,为何查询实体A的时候能同时关联查询实体B并都同时Attached到内存中,而当我执行Detach实体A时,却没能关联Detach实体B,问题根源就在这里,知道这个原因了,现在就是要解决这个问题,如何解决呢?既然知道是Detach实体不全面造成的,那么我只需要获取到当前DbContext上下文对象中现有的所有已Attached实体,在执行完相应的CRUD时,再全部依次Detach掉即可,解决方案代码如下:
在使用的时候配合之前那篇文章的IsAttached函数就能完美解决所有的Attached报错问题了!
public class A { public string a{get;set;} public string b{get;set;} public string c{get;set;} public virtual B b{get;set;} } public class B { public string x{get;set;} public string y{get;set;} public string z{get;set;} } var a1= dbContext.Set<A>().Single(); a1.a="test1"; dbContext.SaveChanges(); dbContext.Detach(a1);//从缓存中移除a1实体; var a2= dbContext.Set<A>().AsNoTracking().Single(); a2.a="test2"; dbContext.Set<A>().Attach(a2); //报错,说B相同的KEY已经有Attached dbContext.Entry(entity).State = EntityState.Modified; dbContext.SaveChanges();
针对这个报错,我在想,为何查询实体A的时候能同时关联查询实体B并都同时Attached到内存中,而当我执行Detach实体A时,却没能关联Detach实体B,问题根源就在这里,知道这个原因了,现在就是要解决这个问题,如何解决呢?既然知道是Detach实体不全面造成的,那么我只需要获取到当前DbContext上下文对象中现有的所有已Attached实体,在执行完相应的CRUD时,再全部依次Detach掉即可,解决方案代码如下:
/// <summary> /// 清空DB上下文中所有缓存的实体对象 /// </summary> private void DetachedAllEntities() { var objectContext = ((IObjectContextAdapter)this.baseContext).ObjectContext; List<ObjectStateEntry> entries = new List<ObjectStateEntry>(); var states = new[] { EntityState.Added, EntityState.Deleted, EntityState.Modified, EntityState.Unchanged }; foreach (var state in states) { entries.AddRange(objectContext.ObjectStateManager.GetObjectStateEntries(state)); } foreach (var item in entries) { objectContext.Detach(item.Entity); } } public void Commit() //封装的统一提交方法 { this.baseContext.SaveChanges(); this.DetachedAllEntities();//执行清除 }
在使用的时候配合之前那篇文章的IsAttached函数就能完美解决所有的Attached报错问题了!
相关文章推荐
- js实现下拉框‘省’,‘市’加载
- Objective-C之内存管理
- WCF_通过使用svcutil.exe将http://*.svc?wsdl生成客户端可调用的.cs文件
- Windows下JAVA用到的环境变量主要有3个,JAVA_HOME、CLASSPATH、PATH。
- 修改Android中默认语言
- [转] 毕业后的五年拉开大家差距的原因在哪里?
- Cell重用重复的解决方法
- 使用vi打开编辑多个文件并在多个文件间复制粘贴内容
- 内存管理(二):copy、retain、assign
- [CareerCup] 1.4 Replace Spaces 替换空格
- jquery bind 传参数
- JDBC数据类型
- 小白有问题-下雨天给linux装adobe flash player更配
- Robot framework+python安装使用图解版
- 浅谈CSRF攻击方式
- .NET微信公众号开发之公众号消息处理
- 安卓手机修改参数工具开发
- 详解Django中的过滤器
- 全志a20android核心板的应用
- 在Fragment中使用viewPager嵌套Fragment遇到的问题(双侧viewpager)