Подтвердить что ты не робот

Операция не может быть завершена, поскольку DbContext был удален с использованием MVC 4

Я знаю, что этот вопрос задают так много раз. Я прочитал и реализовал все решения, но не добился успеха. Я получаю эту ошибку, когда я извлекаю данные из базы данных с помощью EF и связывается с моделью после этого, используя эту модель в представлении.

Мой код контроллера

using System.Linq;
using System.Web.Mvc;
using JsonRenderingMvcApplication.Models;

namespace JsonRenderingMvcApplication.Controllers
{
    public class PublisherController : Controller
    {
        public ActionResult Index()
        {
            PublisherModel model = new PublisherModel();
            using (DAL.DevelopmentEntities context = new DAL.DevelopmentEntities())
            {               
                model.PublisherList = context.Publishers.Select(x =>
                                        new SelectListItem()
                                        {
                                            Text = x.Name,
                                            Value = x.Id.ToString()
                                        }); ;
                           }
            return View(model);
        }

    }
}

Код My View

@model JsonRenderingMvcApplication.Models.PublisherModel

@{
    ViewBag.Title = "Index";
}
<div>
    @Html.DisplayFor(model=>model.Id)
    @Html.DropDownListFor(model => model.Id, Model.PublisherList);
</div>
<div id="booksDiv">

</div>

Мой код модели

using System.Collections.Generic;
using System.Web.Mvc;
using System.ComponentModel.DataAnnotations;

namespace JsonRenderingMvcApplication.Models
{
    public class PublisherModel
    {
        public PublisherModel()
        {
            PublisherList = new List<SelectListItem>();
        }

        [Display(Name="Publisher")]
        public int Id { get; set; }
        public IEnumerable<SelectListItem> PublisherList { get; set; }
    }
}

Мой код объекта

namespace JsonRenderingMvcApplication.DAL
{
    using System;
    using System.Collections.Generic;

    public partial class Publisher
    {
        public Publisher()
        {
            this.BOOKs = new HashSet<BOOK>();
        }

        public int Id { get; set; }
        public string Name { get; set; }
        public string Year { get; set; }

        public virtual ICollection<BOOK> BOOKs { get; set; }
    }
}     

Да, этот объект имеет свойство навигации, но я не хочу данных этого объекта, поэтому я не хочу включать его.

Спасибо

4b9b3361

Ответ 1

Проблема, с которой вы столкнулись, связана с отсроченным исполнением LINQ. Это совершенно для разработчиков, которые еще не поняли, как LINQ работает под капотом. У меня есть замечательная статья в блоге, но основная идея заключается в том, что вы должны принудительно перечислять в коллекции, чтобы привести код LINQ немедленно, а не позже. Это означает следующее:

model.PublisherList = context.Publishers.Select(x =>
    new SelectListItem()
    {
        Text = x.Name,
        Value = x.Id.ToString()
    });

:

model.PublisherList = context.Publishers.Select(x =>
    new SelectListItem()
    {
        Text = x.Name,
        Value = x.Id.ToString()
    }).ToList();

Обратите внимание на .ToList(), который заставляет перечисление.

Ваш запрос LINQ отложен означает, что он не запускается на вашем контроллере, а вместо этого, возможно, в вашем представлении, где вы перебираете коллекцию (которая заставляет перечисление и таким образом запускает LINQ), Поскольку вы используете оператор using, чтобы избавиться от своего контекста БД (что, конечно же, хорошая практика), контекст удаляется, прежде чем вы достигнете представления, которое выполняет код против расположенного контекста. Принуждение перечисления в инструкции using будет запускать код в это время, а не позже, когда контекст будет удален, и предотвратить эту проблему.