关于Entity Framework中的Attached报错的完美解决方案终极版

简介:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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掉即可,解决方案代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/// <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报错问题了!

本文转自 梦在旅途 博客园博客,原文链接:http://www.cnblogs.com/zuowj/p/4650781.html  ,如需转载请自行联系原作者

相关文章
|
存储 开发框架 .NET
Entity Framework基础01
Entity Framework基础01
178 0
Entity Framework基础01
|
SQL 数据库 C++
Entity Framework初体验
Entity Framework初体验
157 0
Entity Framework初体验
|
数据库
Entity Framework 迁移
Entity Framework 迁移
98 0
|
Java API
如何用Java代码在SAP Marketing Cloud里创建contact数据
如何用Java代码在SAP Marketing Cloud里创建contact数据
|
数据库 数据库管理
[UWP小白日记-11]在UWP中使用Entity Framework Core(Entity Framework 7)操作SQLite数据库(一)
原文:[UWP小白日记-11]在UWP中使用Entity Framework Core(Entity Framework 7)操作SQLite数据库(一) 前言   本文中,您将创建一个通用应用程序(UWP),使用Entity Framework Core(Entity Framework 7)框架在SQLite数据库上执行基本的数据访问。
1639 0