连接情景中的CRUD操作:
连接场景中的CRUD操作是一项相当简单的任务,因为默认情况下,上下文会自动跟踪实体在其生命周期中发生的更改,前提是AutoDetectChangesEnabled为true。
以下示例显示了如何在连接方案(在上下文的范围内)中添加,更新和删除实体,然后该实体又将在数据库上执行插入,更新和删除命令。上下文将自动检测更改并更新实体的状态。
断开的实体:
当我们得到一个断开的实体图,甚至一个断开的实体时,我们需要做两件事情。首先,我们需要使用新的上下文实例附加实体,并使上下文知道这些实体。其次,手动为这些实体设置合适的EntityStates,因为新的上下文实例不知道在断开的实体上执行的操作,所以新的上下文不能应用适当的EntityState。
示意图:
DbSet.Add():
DbSet.Add()方法将整个实体图形附加到新的上下文,并自动将添加的实体状态应用于所有实体。
使用父DbSet实体的Add方法将整个实体图附加到具有Added状态的新的上下文实例。调用ctx.Savechanges()将为所有实体执行插入命令,这会将新行插入到适当的数据库表中。
DbSet.Attach():
DbSet.Attach方法将整个实体图形附加到具有不变实体状态的新上下文中。
Attach方法只会将实体图附加到上下文中,所以我们需要为每个实体找到适当的实体状态并手动应用。
DbContext.Entry():
DbContext的Entry方法返回指定实体的DbEntityEntry实例。DbEntityEntry可以用来改变一个实体的状态。
在断开的情况下使用DBContext添加新实体:
在断开的情况下使用DBContext更新现有实体:
步骤:
①从数据库获取现有的学生。
②将学生姓名改为上下文范围(断开模式)
③将修改的实体传递给Entry方法以获取其DBEntityEntry对象,然后将其状态标记为Modified
④调用SaveChanges()方法将学生信息更新到数据库中。
在断开的情况下使用DBContext删除实体:
使用DbContext添加实体图:
我们可以使用DbSet.Add()方法将整个实体图形附加到上下文中,并将所有实体的状态设置为Added。
使用DbContext更新实体图:
在断开的情况下更新实体图是一项复杂的任务。
在断开的场景中更新实体图形的问题在于,上下文不知道在客户端执行了哪些操作。根据下图,新的上下文不知道每个实体的状态:
在断开的情况下识别实体状态的模式:
在断开的情况下,有几种方法(如下所示)来标识实体状态:
- 使用实体的PrimaryKey(Id)属性
- 在实体集中设置一个属性来保存状态 (学习的时候可以这样设计)
1)使用实体的PrimaryKey属性:
您可以使用每个实体的PrimaryKey(Id)属性来确定其实体状态。但是,您必须决定使用以下哪个架构规则:
- 每种类型的实体都必须有Id属性(PK)
- Id属性的默认值应为0
在断开的情况下,context2不知道每个实体的状态。它必须通过使用StandardId来确定Standard实体的状态,并使用TeacherId属性来确定Teacher实体的状态。如果StandardId和TeacherID的值为零,则表示它是一个新的实体,如果它不是零,那么它是一个修改的实体。(这个比较好理解)
优点:
- 无需额外的编码/处理来确定实体状态。
- 很好的表现。
缺点:
- 每个实体类型都需要有一个Id属性。它不能确定没有Id属性的实体的状态。
- 无法识别未更改的实体。即使实体没有被改变,它也被设置为Modified状态。因此,对于未更改的实体存在不必要的数据库更新语句。
- 无法处理删除实体场景。它需要单独处理删除。
2)在每个实体拥有状态:
①创建一个接口,声明一个枚举
②让实体继承改接口
上面的代码修改了一个Teacher,新建了一个Teacher,和新建了一个Standar
优点:
- 无需额外的编码/处理来确定实体状态
- 已添加,已修改,已删除和未更改状态正确
- 没有不必要的更新调用不变的实体。
坏处:
- 需要在断开模式下设置每个实体的适当状态。所以在断线模式下需要格外小心。
实体框架中的并发:
SQL里面处理并发则是使用多线程来处理,对有并发的数据实现同步,只能一个一个的去访问数据。再就是使用锁,在有人访问这个数据的时候别人是访问不了的。
①Student表里面有个RowVersion字段是 timestamp(时间戳)类型,在添加,更新的时候会自动变化
②打开设计器修改Student实体中的RowVersion属性,更改并发模式
③测试并发
数据库中只修改了一次
至于怎么去处理并发这里就不做深入研究了。