我有一个简单的问题。
假设上下文是我的EF上下文,响应者是EF从数据库生成的实际EF实体。
更新受访者的最短途径是什么?
public void UpdateRespondent(Respondent respondent)
{
var resp = context.Respondents.First(r => r.RespondentId == respondent.RespondentId);
// Now... do I have to copy all properties from the respondent into resp ??
// But respondent is actually the Respondent entity
// Can I just replace it somehow?
context.SaveChanges();
}
非常感谢。
UPDATE1
感谢nrodic,这段代码就像一个魅力:
public void UpdateRespondent(Respondent changed)
{
var respondent = db.Respondents.FirstOrDefault(r => r.RespondentId == changed.RespondentId);
db.Respondents.ApplyCurrentValues(changed);
db.SaveChanges();
}
但有一个问题 - 看起来我不需要第一行" var respondent ="在所有!!
知道为什么在许多例子中这条线存在?
感谢。
UPDATE2
嗯,看起来我需要第一行。 否则它会在第二行抛出异常(db.Respondents.ApplyCurrentValues(已更改);)具有与所提供对象的键匹配的键的对象可以 在ObjectStateManager中找不到。验证密钥值 提供的对象匹配对象的键值 必须应用更改。
答案 0 :(得分:0)
你可以这样做:
public void UpdateRespondent(Respondent respondent)
{
var resp = context.Respondents.First(r => r.RespondentId == respondentId);
// Now... do I have to copy all properties from the respondent into resp ??
// But respondent is actually the Respondent entity
// Can I just replace it somehow?
resp.Name = "Bob";
resp.SomeProperty = "SomeValue";
context.SaveChanges();
}
您只需更新resp对象的属性即可。虽然看到第一条评论,但可能并不完全是你所追求的。
答案 1 :(得分:0)
如果加载实体,将其从上下文中分离并更新其属性,则可以使用方法ApplyCurrentValues()
将更改应用于数据库。像这样使用它:
public void UpdateRespondent(Respondent changed)
{
var respondent = db.Respondents.FirstOrDefault(r => r.RespondentId == changed.RespondentId);
db.Respondents.ApplyCurrentValues(changed);
db.SaveChanges();
}
请注意,在调用ApplyCurrentValues()
时,实体必须附加到上下文(从数据库中读取)。否则将抛出InvalidOperationException
:
具有与所提供对象的键匹配的键的对象可以 在ObjectStateManager中找不到。验证密钥值 提供的对象匹配对象的键值 必须应用更改。
如果您使用DbContext
代替ObjectContext
,请务必阅读this question。
更新数据库的另一种方法可能是使用自动映射技术(例如Automapper或ValueInjecter)。这是更一般的情况,因为它允许使用DTO并提供对更新内容(和如何)的良好控制。