EF 的Attach方法



在介绍Attach方法前先介绍与它相关的知识点

  Attach方法:将给定实体以 System.Data.EntityState.Unchanged 状态附加到上下文中

从解释可以看出Attach方法主要目的就是把一个没有被dbContext跟踪的对象附加到dbCotext中使其被dbContext跟踪

1   对象上下文:DBContext 建一个新的上下文实例以创建将连接到的数据库的名称,默认状态是没有对任何对象跟踪的

2   实体状态:  在EF中对实体状会有4种状态:

      2.1  Added:对象为新对象,并且已添加到对象上下文,但尚未调用 

  2.2  Deleted:对象已从对象上下文中删除

  2.3 Detached:对象存在,但没有被跟踪。 在创建实体之后、但将其添加到对象上下文之前,该实体处于此状态

  2.4 Modified:对象上的一个标量属性已更改,但尚未调用 

  2.5 Unchanged: 此对象尚未经过修改自对象附加到上下文中后,或自上次调用 (调用了SaveChange方法后所有的对象都改为Unchanged状态)

了解了相关的知识后就开始利用Attach方法改代码了

以上为原来的方法 

复制代码
using(Entities ctx = new Entities()) 
{
    Product product = ctx.Product.First();
    //更新属性操作
    ctx.SaveChange();
  
}
复制代码
这种写法会产生两次对数据库的操作,改成Attach方法后如下

复制代码
public void Update(Product product)
{

    using(Entities ctx = new Entities) 
   {
     //product 已前台更新后
      ctx.Attach(product);
      ctx.ObjectStateManager.ChangeObjectState(entity,EntityState.Modified)
      ctx.SaveChange();
    }
}
//EF 的处理方式如下
// 1 把对象附加到上下文中,并把状态改为Modified状态
// 2 调用Savechange方法时生成一段Update的SQL语句且Where 条件
//    为对象的主键Id,因为EF更新和删除都是根据主键ID来处理的
复制代码
删除操作也是一样的,这里就只贴用Attach的处理方式了

复制代码
public void Delete(Product product)
{

    using(Entities ctx = new Entities) 
   {
     Product  entity = new Product{Id =1}
     ctx.Attach(entity); ctx.ObjectStateManager.ChangeObjectState(entity,EntityState.Deleted)
     ctx.SaveChange();
    }
}
//前面说了EF是根据主键ID来处理的所以只要手动生成一个对象并把对应的ID赋值然后Attach到上下文中即可做到删除
复制代码


相比项目中原来的方法,用Attach后对数据库的操作相应减少一次,性能上会有较大提升!
原文地址:https://www.cnblogs.com/sayhallotoyou/p/4241464.html