代码之家  ›  专栏  ›  技术社区  ›  Will

处理非跟踪自跟踪实体的正确方法是什么?

  •  4
  • Will  · 技术社区  · 14 年前

    自我跟踪实体。令人惊叹的。

    除非你做类似的事

    return Db.Users;
    

    没有一个自跟踪实体在跟踪(可能直到反序列化它们)。

    好的。因此,我们必须认识到,有一种可能性,即返回我们的实体没有启用跟踪。

    现在怎么办????

    我试过的东西

    对于给定的方法体:

    using (var db = new Database())
    {
        if (update.ChangeTracker.ChangeTrackingEnabled)
            db.Configurations.ApplyChanges(update);
        else
            FigureItOut(update, db);
    
        db.SaveChanges();
        update.AcceptChanges();
    }
    

    以下实现 FigureItOut 全部失败:

    db.Configurations.Attach(update);
    db.DetectChanges();
    

    也不

    db.Configurations.Attach(update);
    db.Configurations.ApplyCurrentValues(update);
    

    也不

    db.Configurations.Attach(update);
    db.Configurations.ApplyOriginalValues(update);
    

    也不

    db.Configurations.Attach(update);
    db.Configurations.ApplyChanges(update
    

    除此之外,我也没有别的办法

    1. 从数据库中获取原始实体
    2. 手工比较每个属性
    3. 根据需要更新属性

    确切地说,我应该如何处理那些不跟踪自己的自我跟踪实体??


    小更新:

    盲目地将实体标记为已修改的工作,但是这似乎有点难闻。在这种情况下我们能做的最好吗?

    1 回复  |  直到 14 年前
        1
  •  6
  •   Will    14 年前

    场景1

    下面是一些建议遵循的实践。 在WCF场景中使用ste时,应该依赖ste实现的变更跟踪器,因此在服务器端执行以下操作。

    db.Users.ApplyChanges(user);
    db.SaveChanges();
    

    情景2 但是,如果您在服务器上,建议的做法是在名为EnableChangeTracking的ObjectContext的分部类上创建一个方法。该方法将查询处于未更改状态的实体,这些实体实现IObjectWithChangeTracker并打开更改跟踪,因此类似于

    user = db.users.first(u => u.userid == 1);
    db.EnableChangeTracking();
    

    现在尝试将用户实体从最初从中检索到的另一个上下文中保存。

    db2.users.ApplyChanges(user);
    db2.SaveChanges();
    

    场景3 如果在服务器端,您连接到从中检索用户实体的同一对象上下文,那么您可以使用ste作为简单的poco对象,如下所示

    user = db.users.first(u => u.userid == 1);
    user.LastName = "XYZ";
    db.DetectChanges(); //no need for it cuz Savechanges implicitly calls this.
    db.SaveChanges();
    

    场景4 如果从不同的上下文中检索用户实体,那么上下文U将使用它进行保存,然后这里还有另一个选项,在该选项中,您将实体标记为已修改,而不关心修改了什么。

    user = db.users.first(u => u.userid == 1);
    var db2 = new ObjectContext();
    user.LastName = "XYZ";
    db2.Users.Attach(user);
    // i prefer this option..
    db2.ObjectStateManager.ChangeObjectState(user,EntityState.Modified); 
    db2.SaveChanges(); // updates all columns
    

    场景5 如果从不同的上下文中检索用户实体,那么上下文U将使用它来保存,然后这里是另一个选项,在其中检索原始实体。

    user = db.users.first(u => u.userid == 1);
    user.lastName ="XYZ";
    var db2 = new ObjectContext();
    db2.Users.First(u => u.userid == user.userid);
    db2.users.ApplyCurrentValues(user);
    db2.SaveChanges();
    

    这是一篇描述了几个场景的博客文章。 http://weblogs.asp.net/zeeshanhirani/archive/2010/03/30/modifying-self-tracking-entity-on-the-server.aspx

    我在我的实体框架4.0食谱书中用很多场景广泛地介绍了这些概念。