我有一个与类别相关联的书签,所以每次我更新现有的书签时,如果该类别已存在,则应创建或更新一个新的类别。当我更新现有书签时,出现以下错误信息:
我的无法跟踪实体类型“Bookmark”的实例,因为具有{'ID'}相同的键值的另一个实例正在被跟踪。在附加现有实体时,请确保只附加一个具有给定键值的实体实例。考虑使用'DbContextOptionsBuilder.EnableSensitiveDataLogging'来查看冲突的键值。
实体
看起来是这样的:public class Bookmark
{
[Key]
public int ID { get; set; }
[StringLength(maximumLength: 500)]
public string URL { get; set; }
public string ShortDescription { get; set; }
public int? CategoryId { get; set; }
public virtual Category Category { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}")]
public DateTime CreateDate { get; set; }
}
我的 Update
控制器如下:
public async Task<IActionResult> Edit(BookmarkViewModel request)
{
var bookmark = _mapper.Map<Bookmark>(request);
var exists = await _bookmarkService.GetBookmark(bookmark.ID);
if(exists == null)
return new StatusCodeResult(Microsoft.AspNetCore.Http.StatusCodes.Status404NotFound);
if (ModelState.IsValid)
{
if (request.CategoryName != null)
{
var category = _categoryService.CreateCategory(new Category
{
Name = request.CategoryName
});
bookmark.Category = category;
bookmark.CategoryId = category.ID;
}
await _bookmarkService.UpdateBookmark(bookmark);
return RedirectToAction("Index");
}
return View(bookmark);
}
我的CreateCategory
服务如下:
public Category CreateCategory(Category category)
{
category.UserId = _identityService.GetUserId();
var existing = _ReadLaterDataContext.Categories
.FirstOrDefault(x => x.Name.Equals(category.Name) && x.UserId.Equals(category.UserId));
if (existing != null)
return existing;
_ReadLaterDataContext.Add(category);
_ReadLaterDataContext.SaveChanges();
return category;
}
我的UpdateBookmark
服务看起来像这样:
public async Task UpdateBookmark(Bookmark bookmark)
{
bookmark.CreateDate = DateTime.Now;
UpdateExistingCategory(bookmark);
_ReadLaterDataContext.Update(bookmark);
await _ReadLaterDataContext.SaveChangesAsync();
}
我的GetBookmark()
方法
public async Task<Bookmark> GetBookmark(int Id)
{
return await _ReadLaterDataContext.Bookmark.Where(x => x.ID == Id && x.UserId.Equals(_identityService.GetUserId())).Include(x => x.Category).FirstOrDefaultAsync();
}