wir umstritten bekommen!
Ich bin nicht einverstanden mit dem allgemeinen MVC + EF Konsens darüber, dass ein Zusammenhang in der gesamten Anfrage am Leben zu halten, ist eine gute Sache für eine Reihe von Gründen:
Low Leistungssteigerung Wissen Sie, wie teuer eine Schaffung neuer Datenbankkontext ist? Gut...„Ein Datacontext ist leicht und ist nicht teuer zu schaffen“, das ist von MSDN
Holen Sie sich das IoC falsch und es wird scheinen gut .., bis Sie online gehen Wenn Sie Ihre IoC-Container einrichten zu entsorgen Dein Kontext für dich und du verstehst falsch, du liegst wirklich falsch. Ich habe zweimal jetzt gesehen massive Speicherlecks von einem IoC-Container erstellt nicht immer einen Kontext richtig entsorgen. Sie werden nicht bemerken, dass Sie es falsch eingerichtet haben, bis Ihre Server während normaler Benutzerlevel zusammenbrechen. Es wird nicht in der Entwicklung passieren, also einige Belastungstests!
Versehentliches Lazy Loading Sie geben ein IQueryable Ihrer letzten Artikel zurück, damit Sie sie auf Ihrer Homepage auflisten können. Eines Tages wird jemand anderes gebeten, die Anzahl der Kommentare neben dem jeweiligen Artikel anzuzeigen. So fügen sie ein einfaches Stück Code auf den View wie so die Anzahl der Kommentare zu zeigen ...
@foreach(var article in Model.Articles) {
<div>
<b>@article.Title</b> <span>@article.Comments.Count() comments</span>
</div>
}
sieht gut aus, funktioniert gut. Sie haben die Kommentare jedoch nicht in die zurückgegebenen Daten aufgenommen. Dadurch wird nun für jeden Artikel in der Schleife ein neuer Datenbankaufruf ausgeführt. Wählen Sie N + 1 Problem. 10 Artikel = 11 Datenbankaufrufe. Okay, der Code ist falsch, aber es ist ein leichter Fehler, so dass es passieren wird.
Sie können dies verhindern, indem Sie Ihren Kontext in Ihrer Datenschicht herunterfahren. Aber bricht der Code nicht mit einer NullReferenceException für article.Comments.Count()? Ja, es wird Sie zwingen, die Datenschicht zu bearbeiten, um die Daten zu erhalten, die für die Ansichtsebene benötigt werden. So sollte es sein.
Code Geruch Es ist nur etwas falsch, die Datenbank von Ihrem View zu treffen. Sie wissen, dass ein IQueryable die Datenbank noch nicht wirklich getroffen hat, also vergessen Sie dieses Objekt. Stellen Sie sicher, dass Ihre Datenbank getroffen wird, bevor sie Ihre Datenebene verlässt.
So ist die Antwort
sollte Ihr Code (meiner Meinung nach) wie dieses
Datalayer sein:
public List<Article> GetArticles()
{
List<Article> model;
using (var context = new MyEntities())
{
//for an example I've assumed your "MyTable" is a table of news articles
model = (from mt in context.Articles
select mt).ToList();
//data in a List<T> so the database has been hit now and data is final
}
return model;
}
Controller:
public ActionResult Index()
{
var model = new HomeViewModel(); //class with the bits needed for you view
model.Articles = _dataservice.GetArticles(); //irrelevant how _dataService was intialised
return View(model);
}
Sobald Sie getan haben, das und versteh das dann vielleicht yo Sie können damit beginnen, mit einem IoC-Containerstruktur-Kontext zu experimentieren, aber definitiv nicht vorher. Kopf meine Warnung - Ich habe zwei große Ausfälle gesehen :)
Aber ehrlich gesagt, was Sie wollen, Programmierung macht Spaß und sollte eine Frage der Vorliebe sein. Ich sage dir nur meine. Aber was auch immer Sie tun, fangen Sie nicht an, den IoC-Kontext pro Controller oder pro Anfrage zu verwenden, nur weil "all die coolen Kids es tun". Tun Sie es, weil Sie wirklich wirklich auf seine Vorteile achten und verstehen, wie es richtig gemacht wird.
'model = context.MyTable.ToList()' - 'ToList()' wird Ihre Abfrage ausführen. In Ihrem Fall würde IQueryable tatsächlich nicht außerhalb des Kontextbereichs arbeiten. – Andrei