【问题标题】:How to update EF entity, when passing modified entity as a parameter?将修改后的实体作为参数传递时如何更新 EF 实体?
【发布时间】:2013-01-08 12:21:00
【问题描述】:

我有一个小问题。

假设 context 是我的 EF 上下文,而 Respondent 是 EF 从数据库中生成的实际 EF Entity。

更新受访者的最短方法是什么?

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();
}

非常感谢。

更新1

感谢 nrodic,这段代码就像一个魅力:

public void UpdateRespondent(Respondent changed)
{
    var respondent = db.Respondents.FirstOrDefault(r => r.RespondentId == changed.RespondentId);

    db.Respondents.ApplyCurrentValues(changed);
    db.SaveChanges();
}

一个问题 - 看起来我不需要第一行“var respondent =”!

知道为什么在许多示例中存在这条线吗?

谢谢。

更新2

嗯,看来我需要第一行。 否则它会在第二行引发异常 (db.Respondents.ApplyCurrentValues(changed);)

具有与所提供对象的键匹配的键的对象可以 在 ObjectStateManager 中找不到。验证的关键值 提供的对象与对象的键值匹配 必须应用更改。

【问题讨论】:

  • 谢谢,但为什么我需要一些 3rd 方库?两者都是同一个实体。受访者是实际的 EF 实体,它不是 VewModel 或任何自定义事物。它是数据库表的 EF 实体。我认为直接一行代码替换可以进行更新。
  • 是否有直接 EF 注入,因为 resp 和响应者是一回事。
  • 也许thisthis 可以提供帮助。
  • 看来我需要它 :) 请查看更新后的帖子

标签: c#-4.0 entity-framework-4


【解决方案1】:

如果您加载实体,将其从上下文中分离并更新其属性,您可以使用方法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


另一种更新数据库的方法是使用自动映射技术(例如AutomapperValueInjecter)。这是更一般的情况,因为它允许使用 DTO 并且可以很好地控制要更新的内容(以及如何)。

【讨论】:

    【解决方案2】:

    你可以这样做:

        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 对象的属性。虽然看到第一条评论可能并不完全符合您的要求。

    【讨论】:

    • 是的,我知道,这就是为什么我在帖子中写道“现在......我必须将所有属性从受访者复制到 resp 中吗??”我正在寻找一个更简单的选择,如果我有 50 个字段怎么办? :)
    • 我可以直接将resp替换为被调查者,还是直接将一个复制到另一个?
    • 您问题下方的评论可能会对您有所帮助。抱歉,这没有帮助!
    • 对不起,错过了 :) 确实,必须有一个简单的方法来做到这一点。我听说 EF 中有一些附加/分离功能...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-26
    • 2016-02-01
    • 1970-01-01
    • 2015-07-25
    • 1970-01-01
    相关资源
    最近更新 更多