正如标题中所提到的,有多少种方法可用?
我只是遇到这种情况:我从一个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'。
有没有其他方法可以达到这个目的?或者你知道的其他更好的方法?或者关于这个主题的任何官方解决方案?
非常感谢。
答案 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无法自动同步关系中的更改。