Soh*_*eil 4 .net entity-framework entity-framework-core .net-core
我编写了一个简单的应用程序,当我导航到编辑页面时,弹出以下错误。
Microsoft.EntityFrameworkCore.Query [10100]
遍历上下文类型“ app.Models.ApplicationDbContext”的查询结果时发生异常。
System.ObjectDisposedException:无法访问已处置的对象。导致此错误的常见原因是,处理从依赖项注入中解决的上下文,然后稍后尝试在应用程序中的其他位置使用相同的上下文实例。如果在上下文上调用Dispose()或将上下文包装在using语句中,则可能会发生这种情况。如果使用依赖项注入,则应让依赖项注入容器负责处理上下文实例。
似乎EF证明了我无法理解的有用信息。该错误的棘手部分是,当我导航到编辑页面时,它会随机发生。有时它可以工作,有时它无法加载某些属性,Edit.cshtml但仍然可以工作,有时应用程序崩溃,仅在我的控制台中提供了错误。另一个奇怪的发生是它剂量不会产生任何500或5xx错误。它只是崩溃并停止应用程序。
这是我的Edit.cshtml内容:
@page
@model EditModel
@{
ViewData["Title"] = "Edit Book";
}
<h2>Edit Book</h2>
<div class="row justify-content-center">
<div class="col-md-6">
<form method="post" class="form-border">
<div asp-validation-summary="All" class="validation-container alert alert-danger"></div>
<div class="form-group">
<label asp-for="Book.Name"></label>
<input asp-for="Book.Name" class="form-control" />
<span class="form-text text-danger" asp-validation-for="Book.Name"></span>
</div>
<div class="form-group">
<label asp-for="Book.Description"></label>
<input asp-for="Book.Description" class="form-control" />
</div>
<div class="form-group">
<label asp-for="Book.Author"></label>
<input asp-for="Book.Author" class="form-control" />
</div>
<input asp-for="Book.Id" type="hidden">
<button type="submit" class="btn btn-primary">Update</button>
<a asp-page="Index" class="btn btn-success">Back To List</a>
</form>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
这是我的Edit.cshtm.cs OnGet方法:
public async void OnGet(int id)
{
Book = await _db.Books.SingleOrDefaultAsync(x => x.Id == id);
if(Book == null)
{
RedirectToPage("Index");
}
}
Run Code Online (Sandbox Code Playgroud)
我在用 .Net Core 2.2.104
另外,当我运行命令时,dotnet ef --version它会生成Entity Framework Core .NET Command-line Tools
2.2.2-servicing-10034
小智 61
当问题不是 VOID 类型的任务时更新的答案 如果您使用的是 void 方法,则接受的答案很好。如果您的方法不是空的,那么简单的解决方案还有另一个潜在的问题。
如果下面的方法也是异步任务,请验证您的控制器方法是否为异步任务。就我而言,问题是我没有在控制器方法上放置异步,但下线方法是异步任务。
干杯!
bra*_*ndo 21
我要发布的不是这个特定问题的答案。但它是相关的,所以只是为了避免让人头疼我发布它。我遇到了同样的错误
System.ObjectDisposedException:无法访问已处理的对象。等等
以下是带有错误的代码(你能看到吗?):
[HttpGet("processs/oxxo-spei/ticket-email/{paymentIdx}")]
public StatusCodeResult ProcessOxxoSpeiTicketEmailAsync(string paymentIdx)
{
var paymentId = paymentIdx.DecodeRef();
var response = _orderEngine.ProcessOxxoSpeiTicketEmailAsync(paymentId);
return StatusCode(200);
}Run Code Online (Sandbox Code Playgroud)
以下更改修复了它:
[HttpGet("processs/oxxo-spei/ticket-email/{paymentIdx}")]
public async Task<StatusCodeResult> ProcessOxxoSpeiTicketEmailAsync(string paymentIdx)
{
var paymentId = paymentIdx.DecodeRef();
var response = await _orderEngine.ProcessOxxoSpeiTicketEmailAsync(paymentId);
// ^^^^I HAD FORGOTTEN TO PUT AWAIT
return StatusCode(200);
}Run Code Online (Sandbox Code Playgroud)
是的,我忘记在使用 EF Core dbcontext 的函数之前放置“await”。添加“等待”修复它。很容易错过它,特别是如果你很累并且在最后期限内。
Tan*_*jel 10
这是因为您的方法返回类型async void。通常,async void在代码中使用时,这是个坏消息,因为:
因此,返回async Task而不是async void从您的方法中返回,如下所示:
public async Task OnGet(int id)
{
Book = await _db.Books.SingleOrDefaultAsync(x => x.Id == id);
if(Book == null)
{
RedirectToPage("Index");
}
}
Run Code Online (Sandbox Code Playgroud)
更多细节:
async Task转换的替代解决方案你已经尝试过...
async Task而不是async void仔细查看我的调用堆栈后,我重写了SaveChangeAsync我的方法DbContext,并进行了调用以更改默认情况下操作的行为async。这导致我的上下文被处理并仍在尝试访问它。
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
int result = await base.SaveChangesAsync(cancellationToken);
// ignore events if no dispatcher provided
if (dispatcher is null) return result;
// dispatch events only if save was successful
await DispatchEventsIfSaveSuccessful();
return result;
}
private async Task DispatchEventsIfSaveSuccessful()
{
var entitiesWithEvents = ChangeTracker
.Entries<Entity>()
.Select(e => e.Entity)
.Where(e => e.Events.Any())
.ToArray();
...
foreach (var entity in entitiesWithEvents)
{
var events = entity.Events.ToArray();
entity.Events.Clear();
foreach (var domainEvent in events)
{
await dispatcher.Dispatch(domainEvent).ConfigureAwait(false);
}
}
}
Run Code Online (Sandbox Code Playgroud)
await dispatcher.Dispatch(domainEvent).ConfigureAwait(continueOnCapturedContext: false);
省略ConfigureAwait(false)
await dispatcher.Dispatch(domainEvent);
ASP.NET Core 不使用 [ SynchronizationContext]。( https://devblogs.microsoft.com/dotnet/configureawait-faq/ )。
当在 上使用ConfigureAwait(false) 选项async Task时,执行任务将不会在此上下文上恢复,而是在线程池线程上恢复。本质上,通过配置该await调用,当线程完成事件分派时,上下文已经被释放。
继续查看从请求开始到失败的每个方法/函数调用,看看您是否可能正在更改via的默认行为或类似的更改。async/awaitConfigureAwait(false)
欲了解更多信息,我强烈建议您关注Stephen Cleary 在他的博客上提供的链接,async了解更多信息。
| 归档时间: |
|
| 查看次数: |
3904 次 |
| 最近记录: |