• EF在NTier架构下的保存注意事项


    EF在N-Tier架构下的保存注意事项

                              szjay


    前提
    一个实体对象必须先进入ObjectContext中才能进行增、删、改的操作。

    新增
    新增的过程很简单,调用AddObject方法即可。

    修改
    如果要修改的实体对象是Detached状态,那么必须先调用AttachTo方法。
    AttachTo方法告诉ObjectContext,虽然当前实体对象没有在ObjectContext中存在,但它并不是一个新的(Added状态)实体对象,而是在数据库中存在,但ObjectContext中未装载而已。
    如果不采用AttachTo方法,那么就需要从数据库中查询一次到ObjectContext中,否则ObjectContext不“认识”此实体对象。

    Detached状态产生的原因有两种:
    1.手工增加了实体对象,但未调用AddObject或Attach方法;
    2.实体对象是从ObjectContext获取的,但随后脱离了ObjectContext;

    一个经典的保存实体对象修改的步骤是:
    //首先查询出实体对象。
    using(Entities ctx = new Entities) //Entities是ObjectContext的派生类。
    {
    Product product = ctx.Product.First();
    }

    //然后实体对象脱离ObjectContext,变为Detached状态,传送到客户端做处理。
    product.Name = "abc"; //客户端修改实体对象的属性值。

    //客户端返回实体对象。
    using(Entities ctx = new Entities) //注意,我们开了另一个ObjectContext。
    {
    ctx.Product.AttachTo(product); //必须先附加,否则当前ObjectContext不认识。AttachTo会把实体对象设置为Unchanged状态。
    ctx.ObjectStateManager.ChangeObjectState(product, EntityState.Modified); //ObjectContext并不知道实体对象已经修改过了,因此需要手工修改实体对象的状态。
    ctx.SaveChanges();
    }

    以上方法适用于单个对象或简单的聚合根,如果遇到复杂的对象图(Object Graph),那么手工修改状态非常麻烦,也容易出错。
    因此我们通常会从ObjectContext中再取出一次对象(PO),然后把客户端传过来的聚合对象当作DTO,再赋值给PO。
    这样方法遇到大数据量的更新时,效率很低(又取了一次数据,并逐个赋值,并且要逐个对比是否被删除)。
    考虑到DTO与PO的结构一样,我们可以用AutoMapping之类的工具简化赋值。

    删除
    ObjectContext删除实体对象时,首先会判断实体对象是否在本身的上下文中,因此在删除前,我们要么先从数据库中Load一次,要么调用AttachTo方法,然后再调用DeleteObject方法。
    实际上,EF删除一个实体对象,只会使用到它的主键字段和时间戳字段,因此我们可以“伪造”一个要删除的实体对象(Stub,不完整实体对象):
    Product product = new Product(){Id=1,Version=2};
    然后调用AttachTo和DeleteObject即可。

    注意
    当一个对象图(Object Graph)中的一个对象附加到了ObjectContext,那么整个对象图的所有对象,都自动附加到了这个ObjectContext。
    一个实体对象只能同时被附加到一个ObjectContext中。

    如果要强制从数据库获取实体对象,可以设置MergeOption属性为NoTracking。
    MergeOption的策略:
    AppendOnly (default): 将新获取的实体对象添加到缓存,忽略那些缓存中已有的实体(注意区别于对象引用)。
    OverwriteChanges: 用从 Store 中新获取的属性值替换那些缓存中被修改的实体属性。
    PreserveChanges: 和 OverwriteChanges 相反,用缓存中修改的属性值替换从 Store 获取的原始值。
    NoTracking: 禁用缓存和状态跟踪,通常用于那些只读环境。

  • 相关阅读:
    第六日会议博客
    第五日会议博客
    第四日会议博客
    第三日会议博客
    第二日会议博客
    第一日会议博客
    Alpha总结展望——前事不忘后事之师
    请坐,我们是专业团队——Alpha冲刺
    微信小程序测试总结
    WeChair项目Beta冲刺(4/10)
  • 原文地址:https://www.cnblogs.com/ego/p/2445457.html
Copyright © 2020-2023  润新知