无法跟踪实体类型“FileRepo”的实例,因为已跟踪另一个具有相同 {'FileID'} 键值的实例

时间:2021-07-06 13:57:32

标签: 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();
        }

1 个答案:

答案 0 :(得分:3)

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

将您的存储库更改为以下内容。如果实体不在 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 属性,您可以为其定义接口:

public interface IEntityWithId 
{ 
   int Id {get;}
}

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

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