2015-06-09 2 views
3

Я видел этот вопрос в миллион раз, но каждое предложение, с которым я столкнулся, похоже, уже охвачено.Экземпляр объекта ObjectContext был удален и больше не может использоваться

У меня есть рамки сущности в моем решении MVC, и у меня есть «хранилище», который пытается восстановить коллекцию MyObject с:

public static List<MyObject> GetMyObjects() 
{ 
    using (var context = new MyEntities()) 
    { 
     return context.MyObjects.Include("Contact").OrderByDescending(o => o.Date).ToList(); 
    } 
} 

Я называю этот метод как часть действия контроллера, который пытается сериализовать:

public JsonResult All() 
{ 
    return Json(MyRepository.GetMyObjects(), JsonRequestBehavior.AllowGet); 
} 

И я получаю следующее сообщение об ошибке:

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

Я не знаю, где включить этот вариант, я ценю реляционные массивы данных «lazy-load» сущности, если и когда они нужны, и я ценю попытку сериализации всей коллекции, действительно попытаюсь загрузите эти (за пределами инструкции using), но у меня есть «Include».

Что я Пробовал

Я попытался «включить», я также обеспечили никакие другие ассоциации не являются частью MyObject класса (т.е. не я никаких других Include() s писать).

ответ

5

Чтобы избежать этого у вас есть несколько вариантов . Не объявляйте свои навигационные свойства как virtual или отключите Lazy Loading Поведение в вашем контексте. Ложная загрузка включена по умолчанию и достигается путем создания экземпляров производных прокси-типов, а затем переопределения virtual свойств для добавления загрузочного крючка. Таким образом, если вы хотите работать с сериализатором я рекомендую отключить отложенной загрузки:

public class YourContext : DbContext 
{ 
    public YourContext() 
    { 
     this.Configuration.LazyLoadingEnabled = false; 
    } 
} 

Эти ссылки могут помочь вам лучше понять, что я объясняю в моем ответе:

Если удалить virtual ключевое слово из ваших навигационных свойств, компания ПОКО не отвечают требованиям d описанных во втором звене, поэтому EF не создаст прокси-класс для ленивой загрузки ваших свойств навигации. Но если вы отключили ленивую загрузку, даже если ваши свойства навигации virtual, они не будут загружены ни в один объект. При использовании сериализатора хорошая идея отключить ленивую загрузку. Большинство сериализаторов работают, обращаясь к каждому свойству экземпляра типа.

В качестве третьего варианта вы можете использовать атрибут JsonIgnore в своих свойствах навигации, которые вы не хотите сериализовать как часть вашего объекта, но, как я сказал ранее, лучшим вариантом является отключение ленивой загрузки.

+0

Блестящий! На данный момент я не дома, чтобы попробовать ваше решение, но я надеюсь. Я дам ему ответ и отзыв, когда он будет проверен и проверен. Еще раз спасибо. +1. –

+0

Пятно на. Спасибо друг. –

+0

Рад помочь вам;) – octavioccl

0

Когда вы используете Include и используете Lazy loading и оберните dbContext в инструкции Using, то, как только он попытается получить связанные объекты, dbContext уже удален. Вы можете попробовать жадную загрузку навигационного имущества, как это:

IQueryable<MyObjects> query = db.MyObjects.Include(m => m.Contact); 

Или вы можете вынуть с помощью заявления, поскольку это ограничивает вашу отложенную загрузку ...

+0

Если я достаю с помощью заявления, я, безусловно, оставив ненужную работу на сборщик мусора? Мне никогда не нравится избавляться от чего-то, что реализует IDisposable. Возможно, я ошибаюсь? –

+0

@JayMee Затем вам нужно использовать загружаемую загрузку (как показано в моем коде здесь), если вы хотите сохранить инструкцию «Использовать» ... – Aram

0

У меня была такая же проблема и решена, как показано ниже;

Я создал новый объект и поместил значения, которые буду использовать после получения объекта из db.

Пример кода:

var listFromDb= db.XTable.Where(x => x.Id > 5).ToList(); 

var list = new List<Package>(); 

foreach (var item in listFromDb) 
{ 
    var a = new Package() 
    { 
      AccountNo = item.AccountNo, 
      CreateDate = item.CreateDate, 
      IsResultCreated = item.IsResultCreated, 
     }; 
     list.Add(a); 
     }