首页 > 解决方案 > 实体框架模型中的集合未更新

问题描述

我有几个简单的模型。一个 PlaylistEntry 模型和一个包含 PlaylistEntry 模型集合的播放列表模型。

播放列表:

    public class Playlist
    {
        private ICollection<PlaylistEntry> playlistEntries;

        public int PlaylistId { get; set; }

        public string Name { get; set; }

        public virtual ICollection<PlaylistEntry> PlaylistEntries
        {
            get => this.playlistEntries ?? (this.playlistEntries = new HashSet<PlaylistEntry>());
            set => this.playlistEntries = value;
        }
    }

播放列表条目

    public class PlaylistEntry
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int PlaylistEntryId { get; set; }

        public string FilePath { get; set; }

        [ForeignKey("Playlist")]
        public int PlaylistId { get; set; }

        [Required]
        public Playlist Playlist { get; set; }
    }

当我将 PlaylistEntry 添加到处于分离状态的播放列表时,我希望当我附加并保存更改时,对 PlaylistEntries 列表的更改也将被保存。他们不保存,列表为空。

这是我的代码:

    var playlist = new Playlist { Name = "My first playlist" };
    using (var context = new MusicPlayerContext(stringBuilder))
    {
        context.Playlists.Add(playlist);
        context.SaveChanges();
    }

    playlist.PlaylistEntries.Add(new PlaylistEntry { FilePath = "lkdfj", PlaylistId = playlist.PlaylistId });

    using (var context = new MusicPlayerContext(stringBuilder))
    {
        context.Playlists.Attach(playlist);
        context.Entry(playlist).State = EntityState.Modified;
        context.SaveChanges();
    }

    using (var context = new MusicPlayerContext(stringBuilder))
    {
        context.Playlists.Include(x => x.PlaylistEntries).ToList();
    }

最后一次 ToList 调用返回我创建的播放列表,但其中的 PlaylistEntries 集合为空。

谁能发现我做错了什么或提出不同的解决方案?我已经花了大约 7 个小时来解决这个问题,但我终其一生都无法弄清楚。

标签: c#databaseentity-frameworkentity-framework-6

解决方案


您缺少的功能是上下文缓存的工作方式。当您将实体(手动或通过从数据库请求实体)附加到上下文时,实体框架会监视它以进行更改并跟踪这些更改。

您已将对象添加到实体的属性中,然后将其添加到上下文中。Entity Framework 现在正在观察它的变化以做任何额外的工作。 以这种方式添加的所有对象都标记为未更改。将父级标记为已更改不会将导航属性标记为已更改

您可以将实体添加到上下文中的属性:

using (var context = new MusicPlayerContext())
{
    Console.WriteLine("Save PlayList 2 (in context add)");
    context.Playlists.Attach(playlist3);
    playlist3.PlaylistEntries.Add(new PlaylistEntry { 
      FilePath = "Entry3", 
      PlaylistId = playlist3.PlaylistId, PlaylistEntryId = 3 
    });
    context.SaveChanges();
}

...在附加父对象后标记两个对象条目。

using (var context = new MusicPlayerContext())
{
    Console.WriteLine("Save PlayList 2 (full attach)");
    context.Playlists.Attach(playlist2);
    context.Entry(playlist2).State = EntityState.Modified;
    context.Entry(playlist2.PlaylistEntries.First()).State = EntityState.Added;
    context.SaveChanges();
}

在这两种情况下,Entity Framework 现在都知道SaveChanges()发生时在 DB 中要做什么。

点网提琴


推荐阅读