asp.net - 无论行已加载到 EF 更改跟踪器中还是未加载到 Entity Framework 中,如何更新实体?

标签 asp.net asp.net-core entity-framework-core dbcontext

我已经检查了该问题的所有内容,但没有一个对我有用。每个人都建议使用 AsNoTracking() 来解决该问题,但它对我的问题没有任何意义,因为我没有更新我从数据库中调用的数据。

我有公司资料更新模式,该公司可以有资料照片也可以没有,但无论如何我都需要更新这些信息。这就是为什么我需要控制公司创建照片或更新照片。让我向您展示下面的代码:

#region /*UpdateCompanyProfile*/
[HttpPost]
public IActionResult UpdateCompanyProfile(Company company, List<IFormFile> files, int FileID)
{
    try
    {
        if (ModelState.IsValid)
        {
            company.ModifiedDate = DateTime.Now;
            _unitOfWorkC.RepositoryCompany.Update(company);
            int firstRequest = HttpContext.Response.StatusCode;
            if (firstRequest == 200)
            {
                _unitOfWorkC.Complete();
                if (files.Count != 0)
                {
                    var File = _fileUploader.FileUploadToDatabase(files);
                    var FileResult = File.Result;
                    FileResult.CompanyID = company.CompanyID;
                    if (FileID == 0)//That's the point where i control that file, is it gonna be update or create.
                    {
                        _unitOfWorkFR.RepositoryFileRepo.Create(FileResult);
                        int secondRequest1 = HttpContext.Response.StatusCode;
                        if (secondRequest1 == 200)
                        {
                            int tryCatch = _unitOfWorkFR.Complete();
                            if (tryCatch != 15)
                            {
                                TempData["JS"] = "showSuccess();";
                            }
                            else
                            {
                                TempData["JS"] = "showError();";
                            }
                        }
                    }
                    else
                    {
                        FileResult.FileID = FileID;
                        _unitOfWorkFR.RepositoryFileRepo.Update(FileResult); //That's the point where i get the error.
                        int secondRequest2 = HttpContext.Response.StatusCode;
                        if (secondRequest2 == 200)
                        {
                            int tryCatch2 = _unitOfWorkFR.Complete();
                            if (tryCatch2 != 15)
                            {
                                TempData["JS"] = "showSuccess();";
                            }
                            else
                            {
                                TempData["JS"] = "showError();";
                            }
                        }
                        else
                        {
                            TempData["JS"] = "showError();";
                        }
                    }
                }
                
            }
            else
            {
                TempData["Message"] = "?irket g?ncelleme i?leminiz ba?ar?s?z!";
                TempData["JS"] = "showError();";
                return RedirectToAction("CompanyProfile");
            }
        }
        else
        {
            TempData["Message"] = "G??ncellemek istedi?iniz veri hatal?!";
            TempData["JS"] = "showError();";
            return RedirectToAction("CompanyProfile");
        }
    }
    catch (Exception ex)
    {
        var log = _logging.Logging(ex.Message, "Exception/Hata", company.CompanyID.ToString(),
            "CompanyProfile/UpdateCompanyProfile", getCurrentUser(), getCurrentUserClaimRole());
        _unitOfWorkLog.RepositoryLog.Create(log);
        _unitOfWorkLog.Complete();
        //TempData["Message"] = ex.Message;
        //TempData["JS"] = "showError();";
        return RedirectToAction("CompanyProfile");
    }
}
#endregion

如您所见,使用 AsNoTracking() 调用该数据在我的情况中没有任何意义。我只在该操作中收到该错误,因此其他 FileRepo 操作运行良好。

这是我的 FileUploadToDatabase() 方法:

        public async Task<FileRepo> FileUploadToDatabase(List<IFormFile> files)
        {
            foreach (var file in files)
            {
                var fileName = Path.GetFileNameWithoutExtension(file.FileName);
                var fileExtension = Path.GetExtension(file.FileName);
                _fileRepo = new FileRepo
                {
                    FileName = fileName,
                    FileExtension = fileExtension,
                    FileType = file.ContentType,
                    CreatedDate= DateTime.Now
                };
                using (var dataStream = new MemoryStream())
                {
                    await file.CopyToAsync(dataStream);
                    _fileRepo.FileData = dataStream.ToArray();
                }
            }
            return _fileRepo;
        }

这就是我的 FileRepo 类:

   public class FileRepo : Base
    {
        [Key]
        public int FileID { get; set; }

        [Required(ErrorMessage = "Required Field !")]
        public string FileName { get; set; }

        [Required(ErrorMessage = "Required Field !")]
        public string FileType { get; set; }

        [Required(ErrorMessage = "Required Field !")]
        public string FileExtension { get; set; }

        public string FilePath { get; set; }
        public bool FilePhotoIsDefault { get; set; }
        public byte[] FileData { get; set; }
        public int? CompanyID { get; set; }
        public Company Company { get; set; }
        #endregion
    }

这是我的工作单元:

enter image description here

这是我的存储库:

enter image description here

enter image description here

这是我的更新模式的查询:

        public IEnumerable<Company> GetByIDForCompanyProfileCompany(int ID)
        {
            return TradeTurkDBContext.Companies.Where(x => x.CompanyID == ID)
               .Include(x => x.Addresses.Where(x => x.IsDeleted == null || x.IsDeleted == false))
               //
               .Include(x => x.Products.Where(x => x.IsDeleted == null || x.IsDeleted == false))
               .ThenInclude(x => x.FileRepos.Where(x => x.IsDeleted == null || x.IsDeleted == false)).AsSplitQuery()
               //
               .AsNoTrackingWithIdentityResolution().ToList();
        }

最佳答案

为了更新 FileResult,您正在使用 DbSet.Update - 它正在尝试将实体附加到 ChangeTracker。如果已经存在具有相同 key 的附加对象,则附加将失败。

将您的存储库更改为以下内容。如果实体不在 ChangeTracker 中,它将更新所有字段,否则它将仅更正所需的属性:

public void Update(T model)
{
    if (model == null)
        throw new ArgumentNullException(nameof(model));

    // I hope your generic repository knows Model Id property
    var entry = _context.ChangeTracker.Entries<T>().FirstOrDefault(e => e.Entity.Id == model.Id);

    if (entry == null)
    {
        // entity not tracked, so attach it
        _dbSet.Update(model);
    }
    else
    {
        // setting values from not tracked object
        if (!ReferenceEquals(model, entry.Entity))
            entry.CurrentValues.SetValues(model);
    }
}

更新

如果通用存储库不知道 Id 属性,您可以为其定义接口(interface):

public interface IEntityWithId 
{ 
   int Id {get;}
}

确保您的类是 IEntityWithId 的实现。然后正确的存储库定义:

public interface IRepository<T> where T: class, IEntityWithId
{
   ...
}

关于asp.net - 无论行已加载到 EF 更改跟踪器中还是未加载到 Entity Framework 中,如何更新实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68271940/

相关文章:

c# - 在 Asp.net Core 中获取 UserManager 类的对象?

c# - .NET Minimal API 正确使用 .AddJsonFile() 和环境变量

c# - 在 .Net Core 3.0 项目中正确设置 ASP.Net Core 授权和身份验证

c# - 在 tabcontainer 中启用 tabpanel

asp.net - 如何在 ASP.NET 网页中嵌入代码块?

azure - ASP.NET Core 1.0 的 Kudu 部署脚本

c# - 如何在 Entity Framework Core 中调用带有多个表联接的存储过程?

c# - 新实体的 EF Core 延迟加载器行为

asp.net-core - 执行脚手架dbcontext时如何使集合复数?

asp.net - 如何在 Sitecore 中创建 Web 服务