一.约定
OnModelCreating 有一些限制需要注意,例如:1.表名不支持使用标签进行标注2.最小长度在 OnModelCreating 中不支持3.正则表达式在 OnModelCreating 中不支持使用标注来丰富模型的验证规则
使用 OnModelCreated 来完成数据库的约束(主键,自增长,表名,列类型等等) 二.加载Include:贪婪加载var orders = from o in context.Orders.Include("OrderDetails") where o.CustomerName == "Mac" select o;延迟加载
另外一个特性就是延迟加载,默认情况下,延迟加载被支持,如果你希望禁用它,必须显式声明,最好的位置是在 DbContext 的构造器中。public MyDomainContext()
{ this.Configuration.LazyLoadingEnabled = false; } 当 EF 访问实体的子实体的时候是如何工作的呢?在访问的时候没有事件发生,EF 通过从你定义的实体派生一个动态的对象,然后覆盖你的子实体集合访问属性来实现。这就是为什么需要标记你的子实体集合属性为 virtual 的原因。总结一下两种加载方式的特点
贪婪加载:
1.减少数据访问的延迟,在一次数据库的访问中返回所有的数据。2.你需要知道你将作什么,并且显式声明延迟加载:1.非常宽容,因为只在需要的时候加载数据,不需要预先计划2.可能因为数据访问的延迟而降低性能,考虑到每访问父实体的子实体时,就需要访问数据库。所以遇到循环应该采用贪婪加载,否则每次循环都会访问数据库EF中对实体状会有4种状态:
1.Added: 对象为新对象,并且已添加到对象上下文,但尚未调用SaveChange之前都是Added(期间若修改对象属性,对象状态 任为Added, 删除该对象时状态变为Detached)4.Modified: 当对象的属性被修改时,如果 AutoDetectChangesEnabled=true,或者调用了DetectChanges(),那么该对象的状态 会被修改为Modified
2.Deleted: 调用对象集合把对象A Remove后,EF标记该对象为准备从数据库中删除,调用SaveChanges()后数据库删除该记录,
并且EF把该对象标记为Detached3.Detached: 对象存在,但尚未被添加到上下文。
5.Unchanged: 当直接从数据库加载到上下文,或者调用Attach附加一个对象时,该对象的状态为Unchanged状态变化:
Added Update -》 Added Added Save -》 Unchanged Added Remove -》 DetachedModified Update -》 Modified
Modified Save -》 Unchanged Modified Remove -》 DeletedDeleted Update -》 Deleted
Deleted Save -》 Detached Deleted Add -》 Added(数据库不会删除原来的数据,并且会新增一条数据)Unchanged Add -》 Added
Unchanged Update -》 Modified Unchanged Save -》 Unchanged Unchanged Remove -》 DeletedDetached Update -》 Detached
Detached Add -》 Added Detached Remove -》 出错OriginalValues:原先值,当对象附加或数据库加载(不是添加,添加时只有当前值没有原先值,添加后调用SaveChanges()才会有原先值)到上下文之后才有原先值。
1.对象被附加或者从数据库中读取到上下文时的值,SaveChanges()后的当前值与原先值保持一致。CurrentValues:当前值,当对象上下文跟踪之后才有当前值。
1.最新的值,即被修改后的最新值,如果值未被修改,那么当前值与原先值一样。
ValidateOnSaveEnabled:保存前验证对象的属性最大最小长度等,默认为true。
1.如果ValidateOnSaveEnabled=true,那么SaveChanges()前不会调用DetectChanges(), 反之如果ValidateOnSaveEnabled=false,那么只有在AutoDetectChangesEnabled=true的情况下,EF在SaveChanges()前才会调用DetectChanges()AutoDetectChangesEnabled:自动跟踪对象的属性变化,默认为true。
1.如果关闭EF自动跟踪,在SaveChanges()前尚未手动调用DetectChanges(),那么保存不会生效。(前提:对象状态为Unchanged) 因为如果AutoDetectChangesEnabled=false,那么EF就不会自动跟踪对象属性的变化,从而导致对象的状态也不会变为Modified, 并且因为AutoDetectChangesEnabled=false,那么EF在SaveChanges() 实际保存到数据库之前不会调用DetectChanges(), 所以最终修改不会生效。2.如果AutoDetectChangesEnabled=true,那么就算不调用DetectChanges(),EF在SaveChanges()时也能生效。 DetectChanges():同步对象与其属性的状态。1.如果对象A的状态为Unchanged,A的属性A1状态为Modified,那么调用DetectChanges()后,A状态变为Modified 2.如果AutoDetectChangesEnabled=true,那么对象与其属性的状态会立即同步AcceptAllChanges():上下文能跟踪状态为Added、Modified、Deleted的所有对象,修改他们的状态为Unchanged。在SaveChanges()失败时不 会调用该方法。
AcceptAllChangesAfterSave:标志SaveChanges()后调用AcceptAllChanges
1.EF6.0在SaveChanges()成功后始终会调用AcceptAllChanges(),把Added、Modified、Deleted的对象状态修改为UnchangedDetectChangesBeforeSave:标志在SaveChanges()前,需要调用DetectChanges()同步所有状态
1.如果AutoDetectChangesEnabled=false,那么在SaveChanges()前,不会调用DetectChanges()同步所有状态SaveChanges():
1.只有当AutoDetectChangesEnabled=true,ValidateOnSaveEnabled=false的情况下,在保存之前才会调用DetectChanges() 2.当保存成功后,始终都会调用AcceptAllChanges()