• [转]EntityFramework状态变化AutoDetectChangesEnabled与SaveChanged参数说明


    一.约定
    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把该对象标记为Detached

    3.Detached: 对象存在,但尚未被添加到上下文。


    5.Unchanged: 当直接从数据库加载到上下文,或者调用Attach附加一个对象时,该对象的状态为Unchanged

    状态变化:
    Added Update -》 Added
    Added Save -》 Unchanged
    Added Remove -》 Detached

    Modified Update -》 Modified
    Modified Save -》 Unchanged
    Modified Remove -》 Deleted

    Deleted Update -》 Deleted
    Deleted Save -》 Detached
    Deleted Add -》 Added(数据库不会删除原来的数据,并且会新增一条数据)

    Unchanged Add -》 Added
    Unchanged Update -》 Modified
    Unchanged Save -》 Unchanged
    Unchanged Remove -》 Deleted

    Detached 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的对象状态修改为Unchanged

    DetectChangesBeforeSave:标志在SaveChanges()前,需要调用DetectChanges()同步所有状态
    1.如果AutoDetectChangesEnabled=false,那么在SaveChanges()前,不会调用DetectChanges()同步所有状态

    SaveChanges():
    1.只有当AutoDetectChangesEnabled=true,ValidateOnSaveEnabled=false的情况下,在保存之前才会调用DetectChanges()
    2.当保存成功后,始终都会调用AcceptAllChanges()

  • 相关阅读:
    cocos3.2触摸事件接收顺序
    触摸点是否在按钮矩形内
    scrollview里container拖动显示问题
    cocos2dx 显示对象尺寸
    allocating an object of abstract class
    学习scorllview
    cocos2dx引用计数
    addchild 报错不能添加nil
    有用的宏
    一段SQL
  • 原文地址:https://www.cnblogs.com/hehexiaoxia/p/5707180.html
Copyright © 2020-2023  润新知