一个偶然的机会,让我注意了EF 的Attach方法,于是深入了解让我大吃一惊

在我所参与的项目中所有的更新操作与删除操作都是把原对象加载出来后,再做处理,然后再保存到数据库,这样的操作不缺点在于每一次的操作都要对数据库进行两次操作,性能上有很大的问题,

于是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 =}
ctx.Attach(entity); ctx.ObjectStateManager.ChangeObjectState(entity,EntityState.Deleted)
ctx.SaveChange();
}
}
//前面说了EF是根据主键ID来处理的所以只要手动生成一个对象并把对应的ID赋值然后Attach到上下文中即可做到删除

相比项目中原来的方法,用Attach后对数据库的操作相应减少一次,性能上会有较大提升!

 

EF 相见恨晚的Attach方法的更多相关文章

  1. 因为相同类型的其他实体已具有相同的主键值。在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 。。。

    因为相同类型的其他实体已具有相同的主键值.在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified&quo ...

  2. 关于Entity Framework更新的几种方式以及可能遇到的问题(附加类型“Model”的实体失败,因为相同类型的其他实体已具有相同的主键值)在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 时如果图形中的任何实体具有冲突键值,则可能会发生上述行为

    在日常使用Entity Framework中,数据更新通常会用到.下面就简单封装了一个DBContext类 public partial class EFContext<T> : DbCo ...

  3. EF架构~Cannot attach the file as database

    回到目录 Cannot attach the file as database这个异常是在EF的code frist里经常出现的,解决方法很简单,只要重新启动一下V11实例即可. CMD> sq ...

  4. EF的表连接方法Include()

    在EF中表连接常用的有Join()和Include(),两者都可以实现两张表的连接,但又有所不同. 例如有个唱片表Album(AlbumId,Name,CreateDate,GenreId),表中含外 ...

  5. EF的表连接方法Include() - nlh774

    在EF中表连接常用的有Join()和Include(),两者都可以实现两张表的连接,但又有所不同. 例如有个唱片表Album(AlbumId,Name,CreateDate,GenreId),表中含外 ...

  6. Entity Framework入门教程(7)--- EF中的查询方法

    这里主要介绍两种查询方法 Linq to entity(L2E)和Sql 1.L2E查询 L2E查询时可以使用linq query语法,或者lambda表达式,默认返回的类型是IQueryable,( ...

  7. .NET Core 使用 EF 出错的解决方法

    在.NET Core 项目钟(类库),使用Entity Framework,建立模型生成数据库时,失败 Could not load assembly 'xxx'. Ensure it is refe ...

  8. Entity Framework(EF的Code First方法)

    EntityFramework,是Microsoft的一款ORM(Object-Relation-Mapping)框架.同其它ORM(如,NHibernate,Hibernate)一样, 一是为了使开 ...

  9. Entity Framework(EF的Model First方法)

    EntityFramework,是Microsoft的一款ORM(Object-Relation-Mapping)框架.同其它ORM(如,NHibernate,Hibernate)一样, 一是为了使开 ...

随机推荐

  1. oracle 分析函数的使用(1)

    LISTAGG(columnName,'拼接符') WITHIN GROUP(ORDER BY clause) --order by 子句决定拼接内容的顺序 LISTAGG(columnName,'' ...

  2. Flex各类型坐标转换(全局、本地、内容坐标间转换)

    Flex包含3种坐标:全局坐标.本地坐标.内容坐标 全局坐标:stage级别,坐标原点为舞台的左上角,如MouseEvent的stageX.stageY坐标. 本地坐标:组件级别的坐标系,相对坐标,坐 ...

  3. sql server使用中遇到的问题记录

    一.sql server 不能连接远程服务器,但可以连接本地的数据库 我目前用的是sql server 2012 sp1,用着用着突然就不能连接远程服务器上的数据库了,崩溃了一天... 修复试了,卸载 ...

  4. Sqlite学习笔记(四)&&SQLite-WAL原理

    Sqlite学习笔记(三)&&WAL性能测试中列出了几种典型场景下WAL的性能数据,了解到WAL确实有性能优势,这篇文章将会详细分析WAL的原理,做到知其然,更要知其所以然. WAL是 ...

  5. 已知2个一维数组:a[]={3,4,5,6,7},b[]={1,2,3,4,5,6,7};把数组a与数组b ,对应的元素乘积再赋值给数组b,如:b[2]=a[2]*b[2];最后输出数组b的元素。

    int[]a={3,4,5,6,7}; int[]b={1,2,3,4,5,6,7}; int[] arry=new int[7]; System.out.print("数组b[]={&qu ...

  6. coursera机器学习笔记-神经网络,学习篇

    #对coursera上Andrew Ng老师开的机器学习课程的笔记和心得: #注:此笔记是我自己认为本节课里比较重要.难理解或容易忘记的内容并做了些补充,并非是课堂详细笔记和要点: #标记为<补 ...

  7. innobackupex --rsync 报错 Error: can't create file (null)/xtrabackup_rsyncfiles_pass1

    在使用最新版的innobackupex(2.3.2): innobackupex /backup --rsync --user=xx --password=xxx 备份时报错: Error: can' ...

  8. Tomcat源码分析之—具体启动流程分析

    从Tomcat启动调用栈可知,Bootstrap类的main方法为整个Tomcat的入口,在init初始化Bootstrap类的时候为设置Catalina的工作路径也就是Catalina_HOME信息 ...

  9. linux 源码安装mysql 5.5

         今天在ubuntu和CentOS下,用源码反复安装了许多次mysql,趁还没忘记,赶紧记下来...      在ubuntu和CentOS下安装过程倒是没什么差别.      0.下载源码, ...

  10. TCP校验和的原理和实现

        http://blog.csdn.net/zhangskd/article/details/11770647 分类: Linux TCP/IP Linux Kernel 2013-09-24 ...