AnyAsync() 错误
Error on AnyAsync()
在我的 ASP.NET Web API 应用程序中,我在我的一项操作中收到以下错误,位于以下行:
var dateExists = await _unitOfWork.GetRepository<Booking>().All()
.AnyAsync(b => b.User.UserName == booking.User.UserName && b.Date == model.Date);
这是错误:
A second operation started on this context before a previous
asynchronous operation completed. Use 'await' to ensure that any
asynchronous operations have completed before calling another method
on this context. Any instance members are not guaranteed to be thread
safe.
但是,如您所见,我正在使用 await
。我还在操作中的所有其他异步操作上使用 await
。那么,可能是什么问题?
编辑:
这是我的全部操作:
[HttpPut]
[Route("Update")]
public async Task<IHttpActionResult> Put(BookingEditBindingModel model)
{
if (!ModelState.IsValid)
{
// Return a bad request response if the model state is invalid...
return BadRequest(ModelState);
}
try
{
var booking = await _unitOfWork.GetRepository<Booking>().FindAsync(model.BookingId);
if (booking == null)
{
return NotFound();
}
// Only Admin is allowed to update other users' data...
if (!User.IsInRole("Admin") && booking.User.UserName != User.Identity.Name)
{
return Unauthorized();
}
// There can only be one entry per date/user.
if (model.Date != booking.Date)
{
var dateExists = await _unitOfWork.GetRepository<Booking>().All()
.AnyAsync(b => b.User.UserName == booking.User.UserName && b.Date == model.Date);
if (dateExists)
{
ModelState.AddModelError("Date", "Data already exists for this date.");
return BadRequest(ModelState);
}
}
booking.Date = model.Date;
// Change other properties...
await _unitOfWork.SaveAsync();
return Ok();
}
catch (Exception ex)
{
return InternalServerError(ex);
}
}
更新:
我禁用了延迟加载,但我仍然遇到问题。看起来,正如其他人所猜测的那样,问题出在 booking.User
,因为第一个查询中的 FindAsync()
不包括 User
。我用下面的替换了第一个查询,问题就解决了。
var booking = await _unitOfWork.GetRepository<Booking>().All()
.Include(b => b.User)
.SingleOrDefaultAsync(b => b.BookingId == model.BookingId);
我要大胆猜测你是否启用了延迟加载。这将导致像 booking.User.UserName
这样的调用去数据库检索值,并将它放在像 AnyAsync
这样的调用中可能导致 DbContext
尝试打开第二个连接来检索在它已经为 AnyAsync
语句打开一个之后的那个值。
这种情况下的快速修复是在调用 AnyAsync
之前检索用户名。
var bookingUserName = booking.User.UserName;
var dateExists = await _unitOfWork.GetRepository<Booking>().All()
.AnyAsync(b => b.User.UserName == bookingUserName && b.Date == model.Date);
更好的解决方法是在您获得 booking
实例的调用中提前检索此信息,这样您就不必进行额外的往返。
就我个人而言,我总是在我的 DbContext
类型上禁用延迟加载,并使用 Include
语句明确指定我希望通过任何调用检索的内容。这使我可以更好地控制我的执行。
在我的 ASP.NET Web API 应用程序中,我在我的一项操作中收到以下错误,位于以下行:
var dateExists = await _unitOfWork.GetRepository<Booking>().All()
.AnyAsync(b => b.User.UserName == booking.User.UserName && b.Date == model.Date);
这是错误:
A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.
但是,如您所见,我正在使用 await
。我还在操作中的所有其他异步操作上使用 await
。那么,可能是什么问题?
编辑:
这是我的全部操作:
[HttpPut]
[Route("Update")]
public async Task<IHttpActionResult> Put(BookingEditBindingModel model)
{
if (!ModelState.IsValid)
{
// Return a bad request response if the model state is invalid...
return BadRequest(ModelState);
}
try
{
var booking = await _unitOfWork.GetRepository<Booking>().FindAsync(model.BookingId);
if (booking == null)
{
return NotFound();
}
// Only Admin is allowed to update other users' data...
if (!User.IsInRole("Admin") && booking.User.UserName != User.Identity.Name)
{
return Unauthorized();
}
// There can only be one entry per date/user.
if (model.Date != booking.Date)
{
var dateExists = await _unitOfWork.GetRepository<Booking>().All()
.AnyAsync(b => b.User.UserName == booking.User.UserName && b.Date == model.Date);
if (dateExists)
{
ModelState.AddModelError("Date", "Data already exists for this date.");
return BadRequest(ModelState);
}
}
booking.Date = model.Date;
// Change other properties...
await _unitOfWork.SaveAsync();
return Ok();
}
catch (Exception ex)
{
return InternalServerError(ex);
}
}
更新:
我禁用了延迟加载,但我仍然遇到问题。看起来,正如其他人所猜测的那样,问题出在 booking.User
,因为第一个查询中的 FindAsync()
不包括 User
。我用下面的替换了第一个查询,问题就解决了。
var booking = await _unitOfWork.GetRepository<Booking>().All()
.Include(b => b.User)
.SingleOrDefaultAsync(b => b.BookingId == model.BookingId);
我要大胆猜测你是否启用了延迟加载。这将导致像 booking.User.UserName
这样的调用去数据库检索值,并将它放在像 AnyAsync
这样的调用中可能导致 DbContext
尝试打开第二个连接来检索在它已经为 AnyAsync
语句打开一个之后的那个值。
这种情况下的快速修复是在调用 AnyAsync
之前检索用户名。
var bookingUserName = booking.User.UserName;
var dateExists = await _unitOfWork.GetRepository<Booking>().All()
.AnyAsync(b => b.User.UserName == bookingUserName && b.Date == model.Date);
更好的解决方法是在您获得 booking
实例的调用中提前检索此信息,这样您就不必进行额外的往返。
就我个人而言,我总是在我的 DbContext
类型上禁用延迟加载,并使用 Include
语句明确指定我希望通过任何调用检索的内容。这使我可以更好地控制我的执行。