我已经查看了该问题的所有内容,但没有一个对我有用。每个人都建议使用 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
}
那是我的工作单元:
这是我的存储库:
这是对我的更新模式的查询:
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();
}
答案 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
{
...
}