2014-01-19 9 views
19

entsorgt wurde. Ich weiß, dass diese Frage so oft gestellt wird. Ich habe alle Lösungen gelesen und implementiert, aber keinen Erfolg erzielt. Ich erhalte diesen Fehler, wenn ich Daten aus der Datenbank mithilfe von EF abrufe und mit dem Modell verbinde, danach dieses Modell in View verwende.Der Vorgang kann nicht abgeschlossen werden, da der DbContext mit MVC 4

Mein Controller-Code ist

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-Code ist

@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> 

Mein Modell Code

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

Meine Einheit Code

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

Ja, diese Entität hat eine Navigationseigenschaft, aber ich will diese Entitätsdaten nicht, also möchte ich diese nicht einschließen.

Dank

+0

Welche Zeile löst die Ausnahme aus? – wdosanjos

+0

@wdosanjos Diese Zeile "@ Html.DropDownListFor (model => model.Id, Model.PublisherList);" wirft eine Ausnahme als Titel des Beitrags –

+0

Obwohl nicht direkt mit diesem Problem verbunden, aber ich hatte interessante Befund für den gleichen Fehler. Ich hatte diese UnitOfWork-Klasse (mit dbcontext-Objekt) und Klasse ABC. Die Klasse ABC verwendete das dbContext-Objekt über die unitOfWork-Klasse. Die beiden Klassen ABC und unitOfWork wurden durch den Container von windsor castle DI instanziiert. Ich bekam den gleichen Fehler und das Problem war in der Art, wie ich die Klasse ABC bei der Initialisierung des DI-Containers registriert hatte. Ich hatte Code geschrieben wie Register (Component.For () .ImplementedBy () **. LifeStyle.Transient **) Ich hatte den Code in Fettschrift verpasst, um mit diesem Problem zu enden. – RBT

Antwort

59

Das Problem, das Sie erleben, ist auf Grund verzögerte Ausführung des LINQ. Für Entwickler, die noch nicht wissen, wie LINQ unter der Haube funktioniert, ist das eine echte Herausforderung. Ich habe einen tollen Blog-Beitrag darüber, aber das Kernkonzept ist, dass Sie eine Aufzählung auf die Sammlung erzwingen müssen, damit der LINQ-Code sofort statt später ausgeführt wird. Dies bedeutet, ändert dies:

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

dazu:

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

Hinweis der .ToList() gibt, die die Aufzählung zwingt.

Ihre LINQ-Abfrage ist defered bedeutet, dass es nicht auf Ihrem Controller ausgeführt wird, sondern stattdessen danach in Ihrer Ansicht, wo Sie Schleife über die Sammlung (die Enumeration und damit die LINQ erzwingt). Da Sie die Anweisung using verwenden, um Ihren DB-Kontext zu verwerfen (was natürlich eine gute Vorgehensweise ist), wird der Kontext entsorgt, bevor Sie die Ansicht erreichen, die den Code für den entsorgten Kontext ausführt. Durch das Erzwingen der Enumeration in der using-Anweisung wird der Code zu diesem Zeitpunkt und nicht später beim Ablegen des Kontexts ausgeführt, um dieses Problem zu vermeiden.

+0

Danke für die Antwort. Kannst du bitte mehr erklären, was ".ToList()" bedeutet? +1 für dich. –

+2

Ausgezeichnete Antwort. @Sandeep. Wenn Sie wissen möchten, was .ToList() tut, empfehle ich Ihnen, die Dokumentation zu lesen. http://msdn.microsoft.com/en-us/library/bb342261%28v=vs.110%29.aspx –

+1

@Sandeep sicher, siehe Davids Kommentar, was '.ToList()' tut.Es erstellt im Grunde eine Liste der Objekte in Ihrem Enumerable. – Haney