dbcontext.SaveChanges();更换模型时不更新

dbcontext.SaveChanges(); not updating when replacing model

我有问题 Entity Framework 6.

我正在尝试更新现有实体,但我想完全替换它而不是一个一个地更新每个 属性。当我替换 属性 并调用 SaveChanges() 时,它会很好地保存到数据库中,但是如果我只想简单地替换整个对象,它什么都不做。

下面注释掉的部分显然可以工作,但是当我尝试替换对象时(在我的例子中是 ninja.ToModel() 对象,它来自 Ninja 视图模型)它不起作用。

显然我遗漏了一些东西,我认为这与 Attach() 有关,但到目前为止我在互联网上找到的所有内容都让我感到困惑。像我想要的那样完全更新对象的正确方法是什么?

public void SaveNinja()
{
    using (var context = new ManagerEntities())
    {
        Ninja nin = context.Ninjas.Find(ninja.ToModel().Id);

        // nin.Name = ninja.Name;
        // nin.Strength = ninja.Strength;
        // nin.Agility = ninja.Agility;
        // nin.Intelligence = ninja.Intelligence;
        // nin.Gold = ninja.Gold;

        context.SaveChanges();
    }

    Close();
}

仅下一行 找到 一个 Ninja 与您传递的 Id 匹配的对象。它显然不会更新找到的对象的属性,因为您没有告诉它这样做。

Ninja nin = context.Ninjas.Find(ninja.ToModel().Id);

如果您不想一一设置对象属性,您可以使用 public 方法。

public class Ninja
{
    public string Id { get; set; }
    public string Name { get; set; }

    public void SetNinja(Ninja ninja)
    {
        Id = ninja.Id;
        Name = ninja.Name;
    }
}

然后找到对象后调用:

Ninja nin = context.Ninjas.Find(ninja.ToModel().Id);
nin.SetNinja(ninja);

因此,如果您加载模型实例,您应该只更改值并保存它。您不希望数据库识别表示相同模型数据的两个实例。

但是,如果您没有从数据库中加载任何内容,而是完全由您自己来替换数据库条目,那么您需要做两件事才能使其正常工作:

  1. 确保主 ID 字段(看起来您在这里称它为 Id)设置为与要替换的对象相同。

  2. 保存之前,请执行以下操作:

    db.Attach(ninja).State = EntityStates.Modified;
    

    该代码片段做了两件事。首先,它将数据库附加到对象(本质上是告诉它"this is the instance of this model you should use")。
    然后,其次,它将 State 设置为 Modified,这告诉数据库需要在调用 SaveChanges() 时将其写回磁盘。