<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Loading

      當在 Entity Framework 中先刪除實體、再修改其ID 、然后重新添加時發現的實體未被刪除

      問題描述

      當在 Entity Framework Core 中先刪除實體、再修改其ID 、然后重新添加時發現的實體未被刪除。

      問題代碼示例

      using MediatR;
      using Microsoft.EntityFrameworkCore;
      using Microsoft.Extensions.DependencyInjection;
      using System.ComponentModel.DataAnnotations.Schema;
      using System.Diagnostics;
      
      var serviceCollection = new ServiceCollection();
      
      serviceCollection.AddDbContext<DbContext, TestDB>(opt => opt.UseInMemoryDatabase("test"));
      serviceCollection.AddScoped<PostRepo>();
      
      var serviceProvider = serviceCollection.BuildServiceProvider();
      
      var id = Guid.NewGuid();
      
      using (var scope = serviceProvider.CreateScope())
      {
      
          PostRepo repo = scope.ServiceProvider.GetRequiredService<PostRepo>();
          DbContext db = scope.ServiceProvider.GetRequiredService<DbContext>();
      
          repo.Save(new Post()
          {
              Id = id,
              Name = "123",
              Tags = new List<Tag>() { new Tag() { PostId = id, TagName = "Tag1" } }
          });
      
          db.SaveChanges();
      }
      
      using (var scope = serviceProvider.CreateScope())
      {
          PostRepo repo = scope.ServiceProvider.GetRequiredService<PostRepo>();
          DbContext db = scope.ServiceProvider.GetRequiredService<DbContext>();
      
          var entity = repo.QueryById(id);
      
          repo.Save(entity);
      
          db.SaveChanges();
      }
      
      
      using (var scope = serviceProvider.CreateScope())
      {
          PostRepo repo = scope.ServiceProvider.GetRequiredService<PostRepo>();
          DbContext db = scope.ServiceProvider.GetRequiredService<DbContext>();
      
          var entity = repo.QueryById(id);
      
          Console.WriteLine($"post.Tag Count {entity?.Tags.Count()}");
      }
      
      public class TestDB : DbContext
      {
          public TestDB(DbContextOptions options) : base(options)
          {
          }
      
      
          protected override void OnModelCreating(ModelBuilder modelBuilder)
          {
      
      
              base.OnModelCreating(modelBuilder);
      
          }
      
          public DbSet<Post> Posts { get; set; }
          public DbSet<Tag> Tags { get; set; }
      }
      
      public class Post
      {
          public Guid Id { get; set; }
          public string Name { get; set; }
      
          [NotMapped]
          public List<Tag> Tags { get; set; }
      }
      public class Tag
      {
          public Guid Id { get; set; }
          public Guid PostId { get; set; }
          public string TagName { get; set; }
      }
      
      public class PostRepo
      {
          private readonly DbContext _db;
          public PostRepo(DbContext db)
          {
              _db = db;
          }
      
          public Post? QueryById(Guid id)
          {
              var post = _db.Set<Post>().Where(x => x.Id == id).FirstOrDefault();
              if (post == null)
                  return null;
              var tags = _db.Set<Tag>().Where(x => x.PostId == id).ToList();
      
              post.Tags = tags;
              return post;
          }
      
          public void Save(Post entity)
          {
              var isExist = _db.Set<Post>().Where(x => x.Id == entity.Id).Any();
              if (isExist)
              {
                  _db.Update(entity);
              }
              else
              {
                  _db.Add(entity);
              }
      
              if (entity.Tags != null)
              {
                  var temp = _db.Set<Tag>().Where(x => x.PostId == entity.Id).ToList();
      
                  //clean old
                  _db.RemoveRange(temp);
      
                  // renew id
                  entity.Tags.ForEach(x => { x.Id = Guid.NewGuid(); });
      
                  // add as new ,this cause old entity state to add
                  _db.AddRange(entity.Tags);
              }
          }
      }
      
      

      問題分析

      當我第一次調用RemoveRange時,ChangeTracker 將 tag 標記為 Delete

      ChangeTracker的Debug View 如下所示

      Tag {Id: 3cb7d0a8-e044-4818-9afd-4f09c20ae60a} Deleted
      

      當執行完 entity.Tags.ForEach(x=>{ x.Id = Guid.NewGuid();});
      ChangeTracker的Debug View 如下所示

      Tag {Id: ac9d9fc7-5a8d-4b2e-9ac7-ca1a2778af8d} Deleted
      

      可以看到 Tag 的Id 產生了變化,這說明 ChangeTracker 追蹤的是對象,自此tag的Id產生了變化,便無法刪除了對于Id的數據了

      當執行后續的AddRanage時,tag就變成了Add
      ChangeTracker的Debug View 如下所示

      Tag {Id: ac9d9fc7-5a8d-4b2e-9ac7-ca1a2778af8d} Added
      

      所以就導致了原先想要刪除Tag的刪除信息丟失。

      根本原因: 就是 add和remove的都是同一個對象的引用,變更Id導致了數據的錯位。

      解決方案

      自行選擇

      1. 使用clone方案
      var items =  entity.Tags.Select(x=>x.Clone()).ToList().ForEach(x => { x.Id = Guid.NewGuid(); });
       _db.AddRange(items);
      
      1. 對于一樣Id的使用更新
       var childItems = entity.Tags;
      var deleteItem = temp.ExceptBy(childItems.Select(x => x.Id), x => x.Id);
      var addItem = childItems.ExceptBy(temp.Select(x => x.Id), x => x.Id);
      var update = childItems.IntersectBy(temp.Select(x => x.Id), x => x.Id);
      
      
      _db.RemoveRange(deleteItem);
      _db.AddRange(addItem);
      _db.UpdateRange(update);
      
      posted @ 2025-03-14 11:32  jnzhcn  閱讀(154)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 免费无码无遮挡裸体视频在线观看| 亚洲高清成人av在线| 成人午夜在线观看日韩| 国产精品自拍中文字幕| 韩国精品一区二区三区在线观看| 浴室人妻的情欲hd三级国产| 午夜福利电影| 大香伊蕉在人线国产免费| 97成人碰碰久久人人超级碰oo | 无码国产偷倩在线播放老年人| 日韩伦理片| 成人午夜在线观看日韩| 亚洲欧美牲交| 九九热在线观看免费视频| 亚洲国产天堂久久综合226114| 九九热在线免费观看视频| 欧美z0zo人禽交另类视频| 69天堂人成无码免费视频| 亚洲av午夜福利精品一区二区 | 亚洲全网成人资源在线观看| 色99久久久久高潮综合影院| 欧美黑人大战白嫩在线| 少妇特殊按摩高潮惨叫无码| 免费超爽大片黄| 亚洲第四色在线中文字幕| 又黄又无遮挡AAAAA毛片| 国产精品中文av专线| 狠狠躁天天躁中文字幕无码| 亚洲成在人网站av天堂| 成人自拍短视频午夜福利| 深夜在线观看免费av| 92国产精品午夜福利免费| 欧洲亚洲成av人片天堂网| 亚洲欧美日韩愉拍自拍美利坚| 午夜福利激情一区二区三区| 大香网伊人久久综合网2020| 衡阳县| 中文字幕无码免费不卡视频| 一区二区三区四区国产综合 | 淮安市| 在线日韩日本国产亚洲|