我尝试更新一个实体,但遇到以下错误:
InvalidOperationException: 实体类型 'BookLoan' 的实例无法被跟踪,因为已经有另一个具有相同关键字的实例正在被跟踪。当添加新实体时,对于大多数关键类型,如果未设置关键字(即如果将关键字属性分配为其类型的默认值),则将创建唯一的临时关键字值。如果您明确地为新实体设置关键字值,请确保它们不会与现有实体或为其他新实体生成的临时值发生冲突。在附加现有实体时,请确保只有一个具有给定关键字值的实体实例附加到上下文中。
我做了一些研究,从我的理解来看,当我使用 _context.Update(bookloan);
时,我似乎正在尝试跟踪一个已经被跟踪的实体,但我不确定该怎么做。
我想要做的是更新数据库中的现有实体/记录。这里是我的get和post控制器,因为我不确定还应该分享什么。
Get
[HttpGet]
public async Task<IActionResult> Return(int? id)
{
if (id == null)
{
return NotFound();
}
if (isBookCheckedOut(id) == false)
{
//Not checked out
return RedirectToAction("Index");
}
else
{
var bookloan = (from book in _context.Books.Where(b => b.BookId == id)
join loan in _context.BookLoans.Where(x => !x.ReturnedOn.HasValue) on book.BookId equals loan.BookID into result
from loanWithDefault in result.DefaultIfEmpty()
select new BookReturnViewModel
{
BookLoanID = loanWithDefault.BookLoanID,
BookID = book.BookId,
Title = book.Title,
StudentID = loanWithDefault == null ? null : loanWithDefault.StudentID,
StudentFristName = loanWithDefault == null ? null : loanWithDefault.Student.FirstName,
StudentLastName = loanWithDefault == null ? null : loanWithDefault.Student.LastName,
//Fines
CheckedOutOn = loanWithDefault == null ? (DateTime?)null : loanWithDefault.CheckedOutOn,
IsAvailable = loanWithDefault == null,
AvailableOn = loanWithDefault == null ? (DateTime?)null : loanWithDefault.DueOn
}).FirstOrDefault();
if (bookloan == null)
{
return NotFound();
}
return View(bookloan);
}
}
发布:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Return(BookReturnViewModel model)
{
if (ModelState.IsValid && isBookCheckedOut(1) == true)
{
var bookloan = new BookLoan()
{
BookLoanID = model.BookLoanID,
BookID = model.BookID,
StudentID = model.StudentID,
CheckedOutOn = (DateTime)model.CheckedOutOn,
DueOn = (DateTime)model.AvailableOn,
ReturnedOn = DateTime.Now
};
try
{
_context.Update(bookloan);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
}
return RedirectToAction("Index");
}
else
{
}
return View();
}
BookLoan
,根据ID从数据库获取现有实体(例如,BookLoan data = db.BookLoans.Where(x => x.BookLoanID == model.BookLoanID).FirstOrDefault();
),根据视图模型更新其属性,然后保存。 - user3559349