Невозможно получить доступ к удаленному объекту.Распространенной причиной этой ошибки является удаление контекста - PullRequest
2 голосов
/ 06 апреля 2019

Я написал простое приложение, и когда я перехожу на свою страницу редактирования, появляется следующая ошибка:

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>

Вот мой Edit.cshtm.cs OnGet метод:

public async void OnGet(int id)
{
    Book = await _db.Books.SingleOrDefaultAsync(x => x.Id == id);

    if(Book == null)
    {
        RedirectToPage("Index");
    }
}

Я использую .Net Core 2.2.104

Также, когда я запускаю команду dotnet ef --version, она генерирует Entity Framework Core .NET Command-line Tools 2.2.2-servicing-10034

Ответы [ 2 ]

5 голосов
/ 06 апреля 2019

Это из-за того, что ваш метод возвращает тип 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");
    }
}

Для более подробной информации:

1 голос
/ 09 мая 2019

То, что я собираюсь опубликовать, НЕ является ответом на этот конкретный вопрос.Но это связано с тем, чтобы просто спасти кого-то от головной боли, я публикую это.Я столкнулся с той же ошибкой

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);
        }

Следующее изменение исправило это:

[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);
        }

Да, все верно, я забыл поставить "ожидание" перед функцией, которая использует dbcontext EF Core.Добавление 'ожидание' исправило это.Так легко пропустить это, особенно если вы устали и не в срок.

...