2015-05-22 4 views
1

Ошибка: Экземпляр ObjectContext был удален и больше не может использоваться для операций, требующих подключения.Ошибка в представлении: объект ObjectContext удален

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

public class categoryList 
{ 
    public static Dictionary<string, string> getCategories() 
    { 
     Dictionary<string, string> myList = new Dictionary<string, string>(); 
     using (ProductContext context = new ProductContext()) 
     { 
      List<CategoryModel> list = 
       (from c in context.Categories select c) 
       .ToList<CategoryModel>(); 

      myList = list 
       .GroupBy(c => c.category, StringComparer.OrdinalIgnoreCase) 
       .ToDictionary(g => g.Key, g => g.First().category, StringComparer.OrdinalIgnoreCase); 
      return myList; 
     } 

    } 
} 

И тогда вот мой взгляд код, который звонит, что:

<div class="form-group"> 
       @Html.LabelFor(model => model.Category, "Category", new { @class = "control-label col-md-2" }) 
       <div class="col-md-10"> 
        @Html.DropDownListFor(model => model.Category.category, newBestPlay.Models.ProductModel.getCategories(), new { @class = "form-control"}) 
        @Html.ValidationMessageFor(model => model.Category) 
       </div> 
      </div> 

Edit: Для того, чтобы помочь кому-то понять мою проблему, я наклеивая весь класс ProductModel:

public class ProductModel 
{ 
    public int ID { get; set; } 

    [Display(Name = "Item #")] 
    public int itemNumber { get; set; } 

    [Required(ErrorMessage = "Required")] 
    [Display(Name = "Product")] 
    [MaxLength(50)] 
    public String product { get; set; } 

    [Required(ErrorMessage = "Required")] 
    [Display(Name = "Description")] 
    [MaxLength(500)] 
    public String description { get; set; } 

    [DefaultValue(true)] 
    [Display(Name = "Active?")] 
    public bool active { get; set; } 

    [Display(Name = "Image Name")] 
    public String imageName { get; set; } 

    [Display(Name = "PDF Name")] 
    public String PDFName { get; set; } 

    [ForeignKey("Category")] 
    public virtual int CategoryID { get; set; } 

    public virtual CategoryModel Category { get; set; } 

    public IEnumerable<SelectListItem> CategoryList { get; set; } 

    public static SelectList getCategories() 
    { 
     Dictionary<string, string> requestList = newBestPlay.Models.categoryList.getCategories(); 

     return new SelectList(requestList, "Key", "Value"); 
    } 


} 

А вот CategoryModel:

public class CategoryModel 
{ 
    public int ID { get; set; } 

    [Required(ErrorMessage = "Required")] 
    [Display(Name = "Category")] 
    [MaxLength(50)] 
    public String category { get; set; } 

    [DefaultValue(true)] 
    [Display(Name = "Active?")] 
    public bool active { get; set; } 
} 
+0

Это не понятно, почему вы получаете список категорий, группируя их (почему существуют дубликаты?), а затем создание словаря, где ключ и значение будут одинаковыми. Почему бы просто не вернуть что-то вроде 'context.Categories.Select (c => c.category) .Distinct (StringComparer.OrdinalIgnoreCase) .ToList()'? –

+1

Какова ваша «модель» и как ее извлекают и устанавливают? Я собираюсь догадаться, что это из EF, и что 'model.Category' загружен лениво, следовательно, ваша ошибка. –

+0

Ошибка, скорее всего, вызвана ленивой загрузкой связанных объектов, таких как доступ к свойству 'ProductModel' или вызову' getCategories() '. –

ответ

2

Это исключение будет выбрано, если ваш контекст настроен для использования LazyLoading. Если включена ленивая загрузка, EF будет извлекать только те объекты, которые вы указали в предложении select.

  1. Если класс «CategoryModel» содержит вложенные объекты, и вы используете Lazy-загрузку, эти объекты не будут извлекаться из базы данных.
  2. Поскольку вы закрываете выбор внутри используемого блока, после того, как контроллер установлен, соединение и, следовательно, контекст уже расположены.
  3. Если вы ссылаетесь на один из объектов внутреннего класса внутри представления, например «Model.InnerClass.Property», вы получите это исключение.

Если предыдущие утверждения верны, вы можете попробовать следующее:

public class categoryList 
{ 
    public static Dictionary<string, string> getCategories() 
    { 
     Dictionary<string, string> myList = new Dictionary<string, string>(); 
     using (ProductContext context = new ProductContext()) 
     { 
      List<CategoryModel> list = 
        (from c in context.Categories.Include("PropertyName") select c) 
        .ToList<CategoryModel>(); 

      myList = list 
      .GroupBy(c => c.category, StringComparer.OrdinalIgnoreCase) 
      .ToDictionary(g => g.Key, g => g.First().category, StringComparer.OrdinalIgnoreCase); 
      return myList; 
     } 
    } 
} 

Если внутренний объект содержит дополнительные объекты, которые вы должны указать, что тоже в include_path, поэтому EF извлекает эту информацию перед утилизацией контекст:

.Include("InnerProperty.NestedProperty") 

Я надеюсь, что это помогает

----- EDIT 1 -----------

Вот пример кода:

public class ProductModel 
{ 
    public virtual CategoryModel Category { get; set; } 
} 

public class CategoryModel 
{ 
    public virtual UserAddress Address {get; set;} 
} 

public class UserAddress 
{ 
    public string Street1 {get; set;} 
} 

Предполагая, что предыдущие модели, Включать будет выглядеть следующим образом:

List<CategoryModel> list = (from c in context.Categories 
              .Include("Category") 
              .Include("Category.Address") 
          select c) 
          .ToList<CategoryModel>(); 
+0

В объявлении списка я получаю эту ошибку: «Указанный путь Include недействителен. EntityType« newBestPlay.DAL.CategoryModel »не объявляет свойство навигации с именем« category ».» – dmikester1

+0

Указанное имя должно соответствовать имени свойства, содержащегося в контексте. В вашем случае будет «Category.InnerPropertyName». Вы также можете попробовать с лямбдами. Включить (р => p.Category.InnerProperty). – Charles

+0

«Указанный путь Include недействителен. EntityType« newBestPlay.DAL.CategoryModel »не объявляет свойство навигации с именем« Категория ».» и второй: «Невозможно преобразовать лямбда-выражение для ввода« string », потому что это не тип делегата» – dmikester1