簡體   English   中英

ASP.NET 核心 - 如何使用實體框架更新現有記錄並同時插入新記錄

[英]ASP.NET Core - How to update existing record and insert a new one at the same time using Entity Framework

在 ASP.NET Core-6 Web API 實體框架中,我希望應用程序同時對數據庫中的同一個 model 執行更新和插入。

我有這段代碼:

public async Task<Response<string>> CreateIdentiticationAsync(CreateIdentiticationDto model)
{
    var response = new Response<string>();
    using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
    {
            try
            {
                var identification = _mapper.Map<Identification>(model);
                var existingIdentifications = await _dbContext.Identifications.Where(e => e.IsModified == false).ToListAsync();
                foreach (var existingIdentification in existingIdentifications)
                {
                    if (existingIdentification != null)
                    {
                        existingIdentification.IsModified = true;
                        _unitOfWork.UserIdentifications.Update(identification);
                        await _unitOfWork.Save();
                    }
                }
                Identification.IsModified = false;
                Identification.Type = model.Type;
                Identification.Name = model.Name;

                await _unitOfWork.UserIdentifications.InsertAsync(identification);
                await _unitOfWork.Save();
                response.StatusCode = (int)HttpStatusCode.Created;
                response.Successful = true;
                response.Message = "Created Successfully!";
                transaction.Complete();
                return response;
            }
            catch (Exception ex)
            {
                transaction.Dispose();
                response.Message = "An error occured";
                response.Successful = false;
                response.StatusCode = (int)HttpStatusCode.BadRequest;
                return response;
            }
    }
}

當用戶想要插入一條新記錄時,我希望應用程序首先檢查 model,如果不存在它應該插入新記錄。

但如果存在,則應該更新所有的IsModified為true,然后前面的go,同時插入一條新記錄。

但是,當不存在記錄時,我可以插入新記錄。 但是我遇到的問題是,當它想要更新和插入新記錄時,出現了這個錯誤:

違反 PRIMARY KEY 約束“PK_identifications”。 無法在 object 'dbo.identifications' 中插入重復鍵。 重復鍵值為 (81fe9b8d-2d9c-4d49-8f92-22afe043e327)。

注意:ID 是 Guid 並且是自動生成的

我該如何解決這個問題?

謝謝

這里要考慮很多事情,在現代 EF 中,我不會使用 unitOfWork 也不需要事務,除非非常具體的情況,您還應該驗證來自傳入 model 值的 ID 是 null 因為 ID 應該是自動生成的(很可能這是你錯誤的根源)。 由於我不知道您的 PK 字段的名稱,因此我不會在我建議的代碼中引入此類驗證。

最后一個建議,避免在您的 controller 上使用此代碼,它違反了單一職責原則。 創建一個您執行業務任務的層,並從您的 controller 調用該層。

這是一個應該有效的簡化建議代碼,不要忘記確保 model ID 中的值是 null。

public async Task<Response<string>> CreateIdentiticationAsync(CreateIdentiticationDto model)
{
    var response = new Response<string>();
    try
    {
        var identification = _mapper.Map<Identification>(model);
        var existingIdentifications = await _dbContext.Identifications.Where(e => e.IsModified == false).ToListAsync();
        foreach (var existingIdentification in existingIdentifications)
        {
            existingIdentification.IsModified = true;
        }

        Identification.IsModified = false;

        // If you already mapped this in line 6 why map those two fields again manually?
        // Identification.Type = model.Type;
        // Identification.Name = model.Name;

        _dbContext.UpdateRange(existingIdentifications);
        _dbContext.Add(identification);
        await _dbContext.SaveChangesAsync();

        response.StatusCode = (int)HttpStatusCode.Created;
        response.Successful = true;
        response.Message = "Created Successfully!";

        return response;
    }
    catch (Exception ex)
    {
        transaction.Dispose();
        response.Message = "An error occured";
        response.Successful = false;
        response.StatusCode = (int)HttpStatusCode.BadRequest;
        return response;
    }
}
 public IActionResult Update(int? id,UpdateEmployeeVM employeeVM)
    {
        ViewBag.Positions = new SelectList(_context.Positions, nameof(Position.Id), nameof(Position.Name));
        Employee existed=_context.Employees.Find(id);
        if(existed==null) { NotFound();}
        if (!_context.Positions.Any(p => p.Id == employeeVM.PositionId)) ModelState.AddModelError("PoitionId", "Choose Id right");
        if (!ModelState.IsValid)
        {
            ViewBag.Positions = new SelectList(_context.Positions, nameof(Position.Id), nameof(Position.Name));
            return View();
        }
        if (employeeVM.Image!=null)
        {
            string result = employeeVM.Image.CheckValidate("image/", 300);
            if (result.Length > 0)
            {
                ViewBag.Positions=new SelectList(_context.Positions,nameof(Position.Id),nameof(Position.Name));
                ModelState.AddModelError("Image", result);
            }
            existed.ImageUrl.DeleteFile(_env.WebRootPath, "assets/img");
            existed.ImageUrl = employeeVM.Image.SaveFile(Path.Combine(_env.WebRootPath, "assets", "img"));
            

            return View();
        }
        existed.PositionId=employeeVM.PositionId;
        existed.FullName=employeeVM.FullName;
       
        existed.ImageUrl = employeeVM.Image.SaveFile(Path.Combine(_env.WebRootPath, "assets", "img"));
        
        _context.SaveChanges();
        return RedirectToAction(nameof(Index));
    }

公共異步任務創建(CreateEmployeeVM employeeVM)

    {
        if (!_context.Positions.Any(p => p.Id == employeeVM.PositionId)) ModelState.AddModelError("PositionId", "bele bir position yoxdu");
        if (!ModelState.IsValid)
        {
            ViewBag.Positions = new SelectList(_context.Positions, nameof(Position.Id), nameof(Position.Name));
            return View();
        }
        string result = employeeVM.Image.CheckValidate(500,"image/");
        if (result.Length > 0)
        {
            ViewBag.Positions = new SelectList(_context.Positions, nameof(Position.Id), nameof(Position.Name));
            ModelState.AddModelError("Image", result);
            return View();
        }
        Employee employee = new Employee
        {
            Name = employeeVM.Name,
            Surname = employeeVM.Surname,
            PositionId = employeeVM.PositionId,
            FacebookUrl = employeeVM.FacebookUrl,
            InstagramUrl = employeeVM.InstagramUrl,
            TwitterUrl = employeeVM.TwitterUrl,
            Salary = employeeVM.Salary,
            ImageUrl = employeeVM.Image.SaveFile(Path.Combine(_env.WebRootPath, "assets", "img"))
        };
        await _context.Employees.AddAsync(employee);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM