实体错误地从跟踪 EF Core 分离

Entity is incorrectly detaching from tracking EF Core

我正在尝试从数据库中查询对象,遍历它们并检查列是否有值,如果没有,则创建一个值并将其分配给该列并将其保存到数据库中。我遇到的问题是实体在查询后分离,所以我无法保存更改。下面是我用来查询和更新实体的代码。

    DateTime runTime = passedDateTime ?? DateTime.Now;
    await using DiscordDatabaseContext database = new();
    DateTime startOfWeek = exactlyOneWeek ? runTime.OneWeekAgo() : runTime.StartOfWeek(StartOfWeek);
    //Add if not in a Weekly Playlist already and if the video was submitted after the start of the week
    List<PlaylistData> pld = await database.PlaylistsAdded.Select(playlist => new PlaylistData
    {
        PlaylistId = playlist.PlaylistId,
        WeeklyPlaylistID = playlist.WeeklyPlaylistID,
        Videos = playlist.Videos.Where(
                video => (video.WeeklyPlaylistItemId == null || 
                          video.WeeklyPlaylistItemId.Length == 0) &&
                         startOfWeek <= video.TimeSubmitted)
            .Select(video => new VideoData
            {
                WeeklyPlaylistItemId = video.WeeklyPlaylistItemId,
                VideoId = video.VideoId
            }).ToList()
    }).ToListAsync().ConfigureAwait(false);
    int count = 0;
    int nRows = 0;
    foreach (PlaylistData playlistData in pld)
    {
        if (string.IsNullOrEmpty(playlistData.WeeklyPlaylistID))
        {
            playlistData.WeeklyPlaylistID = await YoutubeAPIs.Instance.MakeWeeklyPlaylist().ConfigureAwait(false);
        }
        foreach (VideoData videoData in playlistData.Videos)
        {
            PlaylistItem playlistItem = await YoutubeAPIs.Instance.AddToPlaylist(videoData.VideoId, playlistId: playlistData.WeeklyPlaylistID, makeNewPlaylistOnError: false).ConfigureAwait(false);
            videoData.WeeklyPlaylistItemId = playlistItem.Id;
            ++count;
        }
    }
    nRows += await database.SaveChangesAsync().ConfigureAwait(false);

查询工作正常,我得到了所有相关的播放列表和视频行,它们只在指定的列中有正确的数据,并且记录的查询看起来不错,但保存不起作用并调用 database.Entry() 在任何播放列表或视频对象上显示它们都是分离的。我究竟做错了什么?集合是否以不同的方式保存?我的查询应该更改吗?是否有应该更改的初始化设置? (我在 init 上设置的唯一我觉得可能会影响它的设置是 .UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery) 但据我所知,记录的查询甚至没有拆分)

您与 projected objects

一起工作
  • 播放列表数据
  • 视频数据

据我所知,EF 核心不跟踪投影对象。所以解决方案是 select DbSet 的实体对象(指在 database.PlaylistsAddedplaylist.Videos 属性中指定的类型)或 select 更新之前的那些对象,然后更新它们。

更新:

第二个选项的示例代码:

foreach (PlaylistData playlistData in pld)
{
    var playlist = database.PlaylistsAdded
        .Include(x=> x.Videos)
        .First(x => x.PlaylistId == playlistData.playlistData);
    if (string.IsNullOrEmpty(playlistData.WeeklyPlaylistID))
    {
        playlist.WeeklyPlaylistID = await YoutubeAPIs.Instance.MakeWeeklyPlaylist().ConfigureAwait(false);
    }
    foreach (VideoData videoData in playlistData.Videos)
    {
        var video = playlist.Videos.First(x=> x.VideoId == videoData.VideoId);
        PlaylistItem playlistItem = await YoutubeAPIs.Instance.AddToPlaylist(videoData.VideoId, playlistId: playlistData.WeeklyPlaylistID, makeNewPlaylistOnError: false).ConfigureAwait(false);
        video.WeeklyPlaylistItemId = playlistItem.Id;
        ++count;
    }
}

注意:这会产生双重 select,因此第一个选项更可取