之前发表过一篇文章题为《关于Entity Framework中的Attached报错的完美解决方案》,那篇文章确实能解决单个实体在进行更新、删除时Attached的报错,注意我这里说的单个实体,指的是要更新或删除的实体不包含其它实体(比如导航属性就包含其它实体),也就是简单POCO对象;但如果不是呢?那么那篇文章里的方法在一定程度上不起作用了,仍会报错,我开始也想不明白,明明通过IsAttached函数判断要更新的实体并未Attached,但进行Attaching时但仍然报错说有相同Key,开始还以为是MS的BUG,后经过多次反复调试发现,报错是对的,因为他报的错并不是我当前要更新的实体,而是该实体中关联的实体,代码与演示报错如下:(仅是演示代码)

  1. public class A
  2. {
  3. public string a{get;set;}
  4. public string b{get;set;}
  5. public string c{get;set;}
  6. public virtual B b{get;set;}
  7. }
  8.  
  9. public class B
  10. {
  11. public string x{get;set;}
  12. public string y{get;set;}
  13. public string z{get;set;}
  14. }
  15.  
  16. var a1= dbContext.Set<A>().Single();
  17. a1.a="test1";
  18. dbContext.SaveChanges();
  19.  
  20. dbContext.Detach(a1);//从缓存中移除a1实体;
  21.  
  22. var a2= dbContext.Set<A>().AsNoTracking().Single();
  23. a2.a="test2";
  24. dbContext.Set<A>().Attach(a2); //报错,说B相同的KEY已经有Attached
  25. dbContext.Entry(entity).State = EntityState.Modified;
  26. dbContext.SaveChanges();

针对这个报错,我在想,为何查询实体A的时候能同时关联查询实体B并都同时Attached到内存中,而当我执行Detach实体A时,却没能关联Detach实体B,问题根源就在这里,知道这个原因了,现在就是要解决这个问题,如何解决呢?既然知道是Detach实体不全面造成的,那么我只需要获取到当前DbContext上下文对象中现有的所有已Attached实体,在执行完相应的CRUD时,再全部依次Detach掉即可,解决方案代码如下:

  1. /// <summary>
  2. /// 清空DB上下文中所有缓存的实体对象
  3. /// </summary>
  4. private void DetachedAllEntities()
  5. {
  6. var objectContext = ((IObjectContextAdapter)this.baseContext).ObjectContext;
  7. List<ObjectStateEntry> entries = new List<ObjectStateEntry>();
  8. var states = new[] { EntityState.Added, EntityState.Deleted, EntityState.Modified, EntityState.Unchanged };
  9. foreach (var state in states)
  10. {
  11. entries.AddRange(objectContext.ObjectStateManager.GetObjectStateEntries(state));
  12. }
  13.  
  14. foreach (var item in entries)
  15. {
  16. objectContext.Detach(item.Entity);
  17. }
  18. }
  19.  
  20. public void Commit() //封装的统一提交方法
  21. {
  22. this.baseContext.SaveChanges();
  23. this.DetachedAllEntities();//执行清除
  24. }

在使用的时候配合之前那篇文章的IsAttached函数就能完美解决所有的Attached报错问题了!

关于Entity Framework中的Attached报错的完美解决方案终极版的更多相关文章

  1. 关于Entity Framework中的Attached报错的完美解决方案

    我们在使用Entity Framework进行CRUD时,为了提升查询效率,一般均会启动NoTracking,即不追踪变化,设置代码如下: //这是DB First模式下设置方法: aTestEnti ...

  2. 关于Entity Framework中的Attached报错相关解决方案的总结

    关于Entity Framework中的Attached报错的问题,我这里分为以下几种类型,每种类型我都给出相应的解决方案,希望能给大家带来一些的帮助,当然作为读者的您如果觉得有不同的意见或更好的方法 ...

  3. PyCharm 中文 字符 python 报错 的 完美 解决方案!

    PyCharm 中文 字符 python 报错 的 完美 解决方案! #_*_ coding:utf-8_*_ https://www.python.org/dev/peps/pep-0263/ 到p ...

  4. Entity framework 中Where、First、Count等查询函数使用时要注意

    在.Net开发中,Entity framework是微软ORM架构的最佳官方工具.我们可以使用Lambda表达式在Entity framework中DbSet<T>类上直接做查询(比如使用 ...

  5. Entity Framework 教程——Entity Framework中的实体类型

    Entity Framework中的实体类型 : 在之前的章节中我们介绍过从已有的数据库中创建EDM,它包含数据库中每个表所对应的实体.在EF 5.0/6.0中,存在POCO 实体和动态代理实体两种. ...

  6. 解决MyEclipse中的js报错的小方法

    今天,下了个模版,但是导进去的时候发现js会报错.看了下其他都没有错误.而有一个js报错误,请原谅我有点红色强迫症,不能留一点红色 . 错误如下:Syntax error on token " ...

  7. Eclipse中启动tomcat报错:A child container failed during start

    我真的很崩溃,先是workspace崩了,费了好久重建的workspace,然后建立了一个小demo项目,tomcat中启动却报错,挑选其中比较重要的2条信息如下: A child container ...

  8. MyEclipse8.6中提交SVN报错

    上周五(11月27日)的时候,从TortoiseSVN提交项目报错,然后直接从MyEclipse中检出来,修改后提交同样报错. MyEclipse8.6中提交SVN报错,错误提示如下: commit ...

  9. [转]在Entity Framework中使用LINQ语句分页

    本文转自:http://diaosbook.com/Post/2012/9/21/linq-paging-in-entity-framework 我们知道,内存分页效率很低.并且,如果是WebForm ...

随机推荐

  1. MariaDB+Keepalived双主高可用配置MySQL-HA

    利用keepalived构建高可用MySQL-HA,保证两台MySQL数据的一致性,然后用keepalived实现虚拟VIP,通过keepalived自带的服务监控功能来实现MySQL故障时自动切换. ...

  2. Understanding ASP.NET MVC Filters and Attributes

    这篇文章把Asp.net MVC的filter介绍的很详细,值得收藏. http://www.dotnet-tricks.com/Tutorial/mvc/b11a280114-Understandi ...

  3. Hadoop Pig简介、安装、试用

    相比Java的MapReduce api,Pig为大型数据集的处理提供了更高层次的抽象,与MapReduce相比,Pig提供了更丰富的数据结构,一般都是多值和嵌套的数据结构.Pig还提供了一套更强大的 ...

  4. .NET Framework中重点类型的继承关系

    继承关系 Object ├─Array │ └─T[] ├─ArrayList ├─List<T> └─String 集合类型的接口 下图展示了集合类型的各种接口的相互关系.注意,下图中所 ...

  5. Angularjs学习---ubuntu12.04中karma安装配置中常见的问题总结

    karma启动时出现了很多问题: 1.安装karma前提条件 安装karma首先要安装nodejs,npm然后才可以安装karma.nodejs,npm的安装过程可以参考文章:Angularjs学习- ...

  6. Atitit apache 和guava的反射工具

    Atitit apache 和guava的反射工具 apache1 Spring的反射工具类 ReflectionUtils1 Guava 反射工具2 apache  34             7 ...

  7. JS工具

       /*** @author Direction*/ /*** JALJA 命名空间 namespace*/var JALJA= {} ; /*** Interface Class* 接口类需要2个 ...

  8. javascript_core_03之数组

    1.数组:连续存储多个数据,一组连续变量的集合: ①创建空数组:var arr=[]:或者var arr=new Array(): ②创建初始化数组:var arr=[值1,值2,……]:或者var ...

  9. SSM环境搭建(接口编程方式)

    一直用ssm在开发项目,之前都是直接copy别人的项目,今天趁着项目刚刚交付,自己搭建一下ssm环境,做个记录 一.创建项目.引入jar包,因为版本不一样,就不贴出这部分的内容了.个人平时的习惯是,先 ...

  10. React 入门实例教程

    现在最热门的前端框架,毫无疑问是 React . 上周,基于 React 的 React Native 发布,结果一天之内,就获得了 5000 颗星,受瞩目程度可见一斑. React 起源于 Face ...