2015-07-26 3 views
-1

Было много связанных вопросов, но никто не решал мою проблему. Моя цель - генерировать pdf-файл, используя Razor PDF. Итак, у меня есть действие контроллера, которое содержит;Экземпляр ObjectContext был удален при использовании объекта во взгляде

var pdf = new PdfResult(null, "myView"); 
ViewBag.VrList = MyDbQuery.GetExpiredVL(DateTime.Today); 
return pdf; 

MyDbQuery - это другое решение, которое я использую. И у меня есть этот метод:

public static List<VLEntity> GetExpiredVL(DateTime ReportDate) 
{ 
    using (MyDbContext db = new MyDbContext()) 
    { 
     return db.VLEntity.Where(vl => vl.ValidTo.Month == ReportDate.Month && vl.ValidTo.Year == ReportDate.Year).ToList(); 
    } 
} 

мой взгляд выглядит следующим образом:

@foreach (var vrRow in ViewBag.VrList) 
{ 
    @vrRow.VEntity.VssId 
} 

Когда я отладки, я получаю:

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

В подобных вопросах, которые я нашел здесь, говорится в заявлении using. Но вы можете видеть здесь, я уже использовал это. Я очень новичок в ASP.NET и C# вообще, и я буду признателен, если вы придумаете решение для этого.

+0

Объекты в вашем списке принадлежат MyDbContext, которые вы удаляете, как только возвращается список. Вы хотите использовать что-то вроде контейнера IoC, который имеет семантику продолжительности жизни по запросу. Альтернативно отключите ленивую загрузку или включите соответствующие объекты, которые вам нужны. –

+0

@ ta.speot.is, но есть вызов ToList(), который должен извлекать результаты из 'DbContext' в память. Считаете ли вы, что ленивая загрузка по-прежнему остается проблемой? –

+0

В какой строке выбрано исключение? Как вы используете 'VrList'? Если вы вызываете любые свойства Lazy на нем, вам понадобится 'DbContext', чтобы каким-то образом получить эти данные. –

ответ

2

В этом коде:

@foreach (var vrRow in ViewBag.VrList) 
{ 
    @vrRow.VEntity.VssId 
} 

Вы получаете доступ к navigation propertyVEntity. Если вы не отключите ленивую загрузку (которая включена по умолчанию), это свойство не загружается из базы данных при запросе, но только при доступе к свойству (через proxy generation).

В вашем методе доступа к данным вы делаете db.VLEntity.[..].ToList(), но это материализует только возвращаемые запросы VLEntity, а не их навигационные свойства.

В связи с отключенным сценарием (сначала запускается метод действия в контроллере, а затем передает данные в представлении), контекст недоступен, когда вы получаете доступ к свойству навигации.

Для этого вам нужно явно загрузить навигационное свойство (как вы claim you did):

return db.VLEntity 
     .Include(v => v.VEntity) 
     .Where([..]) 
     .ToList(); 

Теперь, когда представление обращается к VEntity свойства списка также материализованные, поэтому ваше мнение не имеет для доступа к базе данных.

Вы также говорите, что это сработало раньше, но тогда вы, вероятно, просто не получили никаких навигационных свойств.

Относно: Best practises in MVC for not disposing the object context?, How to solve the error The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

Альтернативами было бы поддерживать DbContext дольше (чего вам не нужно) и вводить ViewModel, на который вы указываете в контроллере.

Смежные вопросы