【问题标题】:Entity Framework 6 Code First Update Row with Relations实体框架 6 代码优先更新行与关系
【发布时间】:2016-06-28 18:59:06
【问题描述】:

我目前正在使用 EF 6 Code First 构建一个 RestAPI,我有几个模型有一些关系。

我已经成功地添加了项目和所有这些,但现在我正在构建一个“更新”功能,但进展并不顺利。

我目前得到了这段代码,它确实更新了行,但是在具有关系的列上它只是添加新行而不是使用现有的...

数据库控制器

public void UpdateDatabase(int id, DatabaseItem db)
    {
        using (var databasesCtx = new DatabaseContext())
        {
            DatabaseItem existing = databasesCtx.Databases.Include(a => a.Subjects).Include(a => a.Types).FirstOrDefault(d => d.Id == id);

            if(existing != null)
            {
                List<DatabaseSubject> subjects = GetAllSubjects();
                List<DatabaseType> types = GetAllTypes();

                db.Subjects = subjects.Where(s => db.Subjects.Select(b => b.Id).ToList().Contains(s.Id)).ToList();
                db.Types = types.Where(t => db.Types.Select(b => b.Id).ToList().Contains(t.Id)).ToList();

                databasesCtx.Entry(existing).CurrentValues.SetValues(db);
                databasesCtx.SaveChanges();
            }
        }
    }

DatabaseItem - 类

public class DatabaseItem
{
    public int Id { get; set; }

    public virtual ICollection<DatabaseSubject> Subjects { get; set; }

    public byte[] Icon { get; set; }

    public virtual ICollection<DatabaseType> Types { get; set; }

    public string Description { get; set; }

    [Required]
    public Boolean Public { get; set; }
}

DatabaseSubject - 类

public class DatabaseSubject
{
    public int Id { get; set; }

    public string Name { get; set; }

    public ICollection<DatabaseItem> Databases { get; set; }
}

DatabaseType - 类

public class DatabaseType
{
    public int Id { get; set; }

    public string Name { get; set; }

    public ICollection<DatabaseItem> Databases { get; set; }
}

【问题讨论】:

  • GetAllSubjects 和 GetAllTypes 方法是什么样的?
  • 它可能需要更正您的导航属性。

标签: c# entity-framework entity-framework-6 asp.net-web-api2


【解决方案1】:

编辑:

SetValues 从不更新导航属性。当您执行代码时,它只知道传递给您的更新方法的实体的简单/复杂属性的变化。 EF 甚至不知道传递给您的 Update 方法的实体的相关实体。

您必须手动告知 EF 您的对象图中的每个更改

引自https://stackoverflow.com/a/11710813/4834103

我在下面留下了原始答案,因为上面只说明了为什么更新无法正常工作,并且答案可能有助于重新编写您的代码

原答案:

我认为你不应该直接设置

   db.Subjects = ...
   db.Types =...

这些集合由实体框架创建和管理。

您应该删除添加元素到这些集合,但不要用另一个集合覆盖它们。 由于这些是多对多关系,这里是an example关于如何更新实体框架中的多对多关系

基本上,您应该注意应该删除的内容并通过集合的界面删除这些项目。记下应该插入的任何新项目并插入它们。

还有这个:

您必须(急切地、显式地或延迟地)加载集合,以便在设置新值和调用 save 之前对其进行跟踪。否则,您将不会替换集合,而只是将其添加到其中。

查看我引用的similar issue

由于db.Subjectsdb.Types 是延迟加载的,它们应该至少被访问一次以进行初始化。提供的代码在覆盖它们之前不会访问它们,因此它们不会被加载/跟踪,并且更改会作为新行添加

【讨论】:

  • 你是对的!当我首先删除所有然后添加它们时,它现在确实有效。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2014-01-05
  • 2012-10-11
  • 2017-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-31
  • 1970-01-01
相关资源
最近更新 更多