我们还是以订单表为例
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语句,对数据库进行增删改查操作