EF5+MVC4系列(5) 删除的方法 1:系统推荐的先查询后remove删除的方法 2:自己new一个包含主键的类,然后 attach附加 remove删除;3:使用db.Entry 修改状态删除4:EntityState的几种状态
2014-07-08 09:54
573 查看
我们还是以订单表为例
1:系统推荐的方法,先查询出来,然后调用remove方法进行删除
我们删除id大于等于4的
static void Main(string[] args) { Delete(o => o.Id >= 4); //这里的参数是个 lambda 表达式 }
public static void Delete(Expression<Func<Order, bool>> whereLambda) { //先查询 List<Order> orders = db.Order.Where(whereLambda).ToList(); foreach (Order item in orders) { db.Order.Remove(item); //把已经带有代理类状态的实体,调用remove方法,使他的状态为 deleted 状态 } db.SaveChanges(); }
2: 优化版本, 我们自己new一个包含主键的对象,然后调用 attach先附加到上下文中,然后再使用remove方法来删除
我们删除掉id为2的行
public static void Delete2() { Order order = new Order() { Id = 2 }; //默认是 EntityState.Detached 未附加状态 db.Order.Attach(order); //状态从 EntityState.DetachedDetached 变成 EntityState.Unchanged 未修改状态 db.Order.Remove(order); //状态从 EntityState.Unchanged 变成 EntityState.Deleted 删除状态 try { db.SaveChanges(); } catch (Exception) { } }
3:优化版本 调用 db.Entry方法,然后修改状态为 Deleted (实际上 优化2也是使用的优化3一样的实质,就是更改了 EntityState 的状态为 Deleted )
这次我们删除数据库id为3的数据
public static void Delete3() { Order order = new Order() { Id = 3 }; //默认是 EntityState.Detached 未附加状态 //db.Order.Attach(order); //状态从 EntityState.DetachedDetached 变成 EntityState.Unchanged 未修改状态 //db.Order.Remove(order); //状态从 EntityState.Unchanged 变成 EntityState.Deleted 删除状态 DbEntityEntry<Order> entry = db.Entry(order); entry.State = EntityState.Deleted; try { db.SaveChanges(); } catch (Exception) { } }
我们用 Sql Server Profiler监控可以看到 id为3的数据已经被删除了
小结: EntityState的几种状态
Detached:对象存在,但未由对象服务跟踪。在创建实体之后、但将其添加到对象上下文之前,该实体处于此状态;
Unchanged:自对象加载到上下文中后,或自上次调用 SaveChanges() 方法后,此对象尚未经过修改;
Added:对象已添加到对象上下文,但尚未调用 SaveChanges() 方法;
Deleted:使用 DeleteObject(System.Object) 方法从对象上下文中删除了对象;
Modified:对象已更改,但尚未调用 SaveChanges() 方法。
原理:在EF中有一个叫做对象管理容器(ObjectStateManager)的东东,如果你希望对某些对象进行增加、删除、修改,查询的操作,那么你首先需要把这些实体对象添加到这个对象管理容器中,(查询出来的实体默认已经添加进去,不用手动添加了)。但是假如你把好几个对象都添加到了EF的对象管理容器中(ObjectStateManage)那么提交的时候,系统(EF)怎么知道你是增加、删除还是修改呢?这时就需要另外一个东东出场了,它叫做DbEntityEntry(一个伪包装类)。这个伪包装类会自动把你放到对象管理容器中的对象包裹起来,这时你放进去的实体默认都放到一个自动产生的伪包装类中,这个类还有一个很重要的属性就是对象的状态,是一个枚举类型的值。有Add、Deleted、Detached、Modified、Unchanged这样几个值,这几个值得意思就不用我讲解了吧,相信大家一看都懂。这是db.savechanges()的时候EF就会根据实体和实体状体生成相应的sql语句,对数据库进行增删改查操作
相关文章推荐
- 关于Entity Framework更新的几种方式以及可能遇到的问题(附加类型“Model”的实体失败,因为相同类型的其他实体已具有相同的主键值)在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 时如果图形中的任何实体具有冲突键值,则可能会发生上述行为
- 附加类型“UniversalReviewSystem.Models.ApplicationUser”的实体失败,因为相同类型的其他实体已具有相同的主键值。在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 时如果图形中的任何实体具有冲突键值
- 使用标记方式entry方法进行删除和修改
- MVC001 EF修改数据库的几种方法,Attach,Entry,部分数据修改
- DLINQ 使用DataContext快速构建数据访问层DAL,发现Updata采用Attach(Entity t,true)困难重重!(如果实体声明了版本成员或者没有更新检查策略,则只能将它附加为没有原始状态的已修改实体)的解决办法!
- vista忘记用户名密码的修改方法(使用PE进入系统,用cmd.exe冒充虚拟键盘,然后就可以mmc组策略,或者命令行添加用户并提升权限)
- 使用 sp_attach_db 系统存储过程附加数据库时(转载)
- 错误:因为相同类型的其他实体已具有相同的主键值。在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 解决方法
- 使用Drupal的db_drop_primary_key方法删除主键出错
- 因为相同类型的其他实体已具有相同的主键值。在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 。。。
- 在LINQ to SQL中使用Translate方法以及修改查询用SQL 推荐
- 获取系统时间几种方法 和 使用CPU时间戳进行高精度计时
- 修改grub引导的Linux和Windows双系统的启动顺序和删除Linux系统的方法
- 创建缩略图的几种方法(都是从网上搜罗的,只是使用后发表自己的评价)
- 在LINQ to SQL中使用Translate方法以及修改查询用SQL
- 添加、删除、修改、查询的四个基本方法
- instsrv.exe下载和使用方法(添加删除系统服务工具)
- 四种方法实现VC枚举系统当前进程[包含自己注释]
- [转自JeffreyZhao]在LINQ to SQL中使用Translate方法以及修改查询用SQL
- SQL Server 2005中专用管理员连接 (DAC) 使用技巧&修改系统表的方法