实体框架6代码第一次更新行与关系

本文关键字:关系 更新 第一次 框架 代码 实体 | 更新日期: 2023-09-27 17:52:41

我目前正在使用EF 6代码构建RestAPI。首先,我得到了几个有一些关系的模型。

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

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

DatabaseController

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 - Class

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

databasessubject - Class

public class DatabaseSubject
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<DatabaseItem> Databases { get; set; }
}

DatabaseType - Class

public class DatabaseType
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<DatabaseItem> Databases { get; set; }
}

实体框架6代码第一次更新行与关系

编辑:

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

你必须手动告诉EF你的对象图中的每一个变化

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

我把原来的答案留在下面,因为上面只告诉了为什么更新不能正常工作,答案可能有助于重做你的代码

原始答:

我认为你不应该直接设置

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

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

应该删除添加元素到这些集合中,但不能用另一个集合覆盖元素。由于这些是多对多关系,这里有一个关于如何在实体框架

中更新多对多关系的示例

基本上,您应该注意应该删除什么,并通过集合的接口删除这些项。注意任何应该插入的新项并插入它们。

:

您必须加载集合(急切地、显式地或惰性地),以便在设置新值和调用save之前可以跟踪它。否则,您将不会替换集合,而只是添加它。

查看我引用的这个类似的问题。

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