Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Razor pages ef core-CRUD如何在编辑时修改嵌套集合?DBConcurrencyException_C#_Asp.net_Entity Framework_Razor_Entity Framework Core - Fatal编程技术网

C# Razor pages ef core-CRUD如何在编辑时修改嵌套集合?DBConcurrencyException

C# Razor pages ef core-CRUD如何在编辑时修改嵌套集合?DBConcurrencyException,c#,asp.net,entity-framework,razor,entity-framework-core,C#,Asp.net,Entity Framework,Razor,Entity Framework Core,在我的项目中,我将LazyLoading与EF Core结合使用,我有两个实体: public class OfferEntity : BaseEntity { public string Category { get; set; } public virtual List<ImagePreviewEntity> ImagePreviews { get; set; } } public class ImagePre

在我的项目中,我将LazyLoading与EF Core结合使用,我有两个实体:

    public class OfferEntity : BaseEntity
    {

        public string Category { get; set; }
        public virtual List<ImagePreviewEntity> ImagePreviews { get; set; }

    }

    public class ImagePreviewEntity: BaseEntity
    {

        public string PreviewUrl { get; set; }

    }
有两个问题我无法解决:

  • ImagePreviews更改不会保存在父实体上
  • 删除空的ImagePreviews会导致DbUpdateConcurrencyException:数据库操作预期会影响1行,但实际影响0行
  • 我所尝试的:

  • 从scopeFactory注入dbСontext
  • 将删除的实体标记为状态=已删除
  • 直接从上下文加载带有include(imagePreview)的dbSet,而不是附加
  • 从OfferEntity.ImagePreviews集合中删除实体
  • 手鼓舞

  • 我错过了什么?

    在与EF斗争了一天之后,找到了一个不优雅但有效的解决方案。 其中一些问题是:

  • 我的新实体没有ID
  • “编辑剃须刀”页面中的现有实体没有附加ID
  • 我多次尝试附加嵌套属性
  • 这是我的OnPostAsync:

        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
                return Page();
    
            var newImages = OfferEntity.ImagePreviews
                .Where(x => string.IsNullOrEmpty(x.Id))
                .ToList();
    
            foreach (var imagePreviewEntity in newImages)
            {
                imagePreviewEntity.Id = Guid.NewGuid().ToString();
                await _context.ImagePreviews.AddAsync(imagePreviewEntity);
            }
    
            _context.Attach(OfferEntity).State = EntityState.Modified;
    
            var relatedPreviewIds = OfferEntity.ImagePreviews.Select(x => x.Id).ToList();
            var previews = await _context.ImagePreviews
                .Where(x => relatedPreviewIds.Contains(x.Id))
                .ToListAsync();
    
            previews.ForEach(entity =>
            {
                _context.Entry(entity).CurrentValues.SetValues(OfferEntity.ImagePreviews.First(p => p.Id == entity.Id));
                if (string.IsNullOrEmpty(entity.PreviewUrl))
                {
                    _context.Attach(entity).State = EntityState.Deleted;
                    return;
                }
    
                if (_context.Entry(entity).State != EntityState.Added)
                    _context.Attach(entity).State = EntityState.Modified;
            });
    
            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException ex)
            {
                if (!OfferEntityExists(OfferEntity.Id))
                    return NotFound();
    
                throw;
            }
    
            return RedirectToPage("./Index");
        }
    
    公共异步任务OnPostAsync() { 如果(!ModelState.IsValid) 返回页(); var newImages=OfferEntity.ImagePreviews .Where(x=>string.IsNullOrEmpty(x.Id)) .ToList(); foreach(新图像中的var imagePreviewEntity) { imagePreviewEntity.Id=Guid.NewGuid().ToString(); wait_context.ImagePreviews.AddAsync(imagePreviewEntity); } _Attach(OfferEntity).State=EntityState.Modified; var relatedPreviewWids=OfferEntity.ImagePreviews.Select(x=>x.Id.ToList(); var previews=wait_context.ImagePreviews .Where(x=>relatedPreviewWids.Contains(x.Id)) .ToListAsync(); previews.ForEach(实体=> { _context.Entry(entity).CurrentValues.SetValues(OfferEntity.ImagePreviews.First(p=>p.Id==entity.Id)); if(string.IsNullOrEmpty(entity.PreviewUrl)) { _context.Attach(entity).State=EntityState.Deleted; 返回; } if(_context.Entry(entity.State!=EntityState.Added) _context.Attach(entity.State=EntityState.Modified; }); 尝试 { wait_context.SaveChangesAsync(); } 捕获(DbUpdateConcurrencyException ex) { 如果(!OfferEntityExists(OfferEntity.Id)) 返回NotFound(); 投掷; } 返回页首(“/索引”); } 我觉得一定有更干净的解决办法。为了从嵌套列表中添加/删除实体而编写尽可能多的代码是愚蠢的

        public async Task<IActionResult> OnGetAsync(string id)
        {
            OfferEntity = await _context.Offers.Include(x => x.ImagePreviews).FirstOrDefaultAsync(m => m.Id == id);
            return Page();
        }
    
        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
                return Page();
    
            //await _context.Offers.Include(p => p.ImagePreviews).LoadAsync();
    
            var toRemove = OfferEntity.ImagePreviews
                .Where(x => string.IsNullOrEmpty(x.PreviewUrl))
                .ToList();
    
            _context.Attach(OfferEntity).State = EntityState.Modified;
            _context.ImagePreviews.RemoveRange(toRemove);
            await _context.SaveChangesAsync();
            
            return return RedirectToPage("./Index");
         }
    
        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
                return Page();
    
            var newImages = OfferEntity.ImagePreviews
                .Where(x => string.IsNullOrEmpty(x.Id))
                .ToList();
    
            foreach (var imagePreviewEntity in newImages)
            {
                imagePreviewEntity.Id = Guid.NewGuid().ToString();
                await _context.ImagePreviews.AddAsync(imagePreviewEntity);
            }
    
            _context.Attach(OfferEntity).State = EntityState.Modified;
    
            var relatedPreviewIds = OfferEntity.ImagePreviews.Select(x => x.Id).ToList();
            var previews = await _context.ImagePreviews
                .Where(x => relatedPreviewIds.Contains(x.Id))
                .ToListAsync();
    
            previews.ForEach(entity =>
            {
                _context.Entry(entity).CurrentValues.SetValues(OfferEntity.ImagePreviews.First(p => p.Id == entity.Id));
                if (string.IsNullOrEmpty(entity.PreviewUrl))
                {
                    _context.Attach(entity).State = EntityState.Deleted;
                    return;
                }
    
                if (_context.Entry(entity).State != EntityState.Added)
                    _context.Attach(entity).State = EntityState.Modified;
            });
    
            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException ex)
            {
                if (!OfferEntityExists(OfferEntity.Id))
                    return NotFound();
    
                throw;
            }
    
            return RedirectToPage("./Index");
        }