附加与另一个ObjectContext分离的实体对象的最佳做法是什么?

时间:2011-02-07 06:21:36

标签: entity-framework-4 objectcontext detach

正如标题中所提到的,有多少种方法可用?

我只是遇到这种情况:我从一个ObjectContext获取一个实体对象,然后从OjbectContext对象中分离实体obejct,然后返回它。

稍后,如果我对此对象进行了一些更改,并且我想将更改保存回数据库。我想我应该这样写,对吗? (嗯,这对我有用。)

public Url GetOneUrl()
{
    Url u;
    using(ServicesEntities ctx = new ServicesEntities())
    {
        u = (from t in ctx.Urls select t).FirstOrDefault<Url>();
        ctx.Detach(u);
    }
    return u;
}

public void SaveToDB(Url url)
{
   using(ServicesEntities ctx = new ServicesEntities())
   {
       var t = ctx.GetObjectByKey(_Url.EntityKey) as Url;
       ctx.Detach(t);
       ctx.Attach(url);
       ctx.ObjectStateManager.ChangeObjectState(url, System.Data.EntityState.Modified);
       ctx.SaveChanges();
   }
}

Url url = GetOneUrl();
url.UrsString = "http://google.com"; //I just change the content.
SaveToDB(url);

public void SaveToDB(Url url)
{
    using(ServicesEntities ctx = new ServicesEntities())
    {
        var t = ctx.GetObjectByKey(_Url.EntityKey) as Url;
        t = url; //this will make t.UrlString becomes "http://google.com"
        ctx.ApplyCurrentValues<Url>("Urls", t);
        ctx.SaveChanges();
    }
}

这种方式对我也有用。

第一种方法会生成sql语句来更新Url表的所有列,但第二种方法会提供一个sql脚本只更新“UrlString”列。

他们都必须从数据库中检索临时实体对象,这是上面代码中的't'。

有没有其他方法可以达到这个目的?或者你知道的其他更好的方法?或者关于这个主题的任何官方解决方案?

非常感谢。

1 个答案:

答案 0 :(得分:0)

我不明白你的第一个例子。为什么你首先从ObjectContext获得实体?它不是必需的,因为您刚刚创建了上下文的新实例。你可以使用:

public void SaveToDB(Url url)
{
   using(ServicesEntities ctx = new ServicesEntities())
   {
       ctx.Attach(url);
       ctx.ObjectStateManager.ChangeObjectState(url, System.Data.EntityState.Modified);
       ctx.SaveChanges();
   }
}

在你的第二个例子中,你可以打电话:

public void SaveToDB(Url url) 
{     
  using(ServicesEntities ctx = new ServicesEntities())     
  {         
     var t = ctx.GetObjectByKey(_Url.EntityKey) as Url; // Ensures that old values are loaded
     ctx.ApplyCurrentValues<Url>("Urls", url);         
     ctx.SaveChanges();     
  } 
} 

现在两种方法之间的区别很明显。第一种方法(Attach)不需要先查询数据库。第二种方法(ApplyCurrentValues)需要首先查询数据库以获取旧值。

您可以使用其他两种方法。 First只是您以前方法的延伸。它允许您定义哪些属性已更改。第二种方法是与加载的实体手动同步。这种方法不使用任何特殊方法。您只需手动将加载的实体属性设置为所需的值。如果使用对象图而不是单个实体,则此方法很有用,因为EF无法自动同步关系中的更改。