Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
von Microsoft
Das Ziel dieses Tutorials besteht darin, eine Methode zum Erstellen von Modellklassen für eine ASP.NET MVC-Anwendung zu erläutern. In diesem Tutorial erfahren Sie, wie Sie Modellklassen erstellen und den Datenbankzugriff durchführen, indem Sie die Vorteile von Microsoft LINQ to SQL nutzen.
Das Ziel dieses Tutorials besteht darin, eine Methode zum Erstellen von Modellklassen für eine ASP.NET MVC-Anwendung zu erläutern. In diesem Tutorial erfahren Sie, wie Sie Modellklassen erstellen und den Datenbankzugriff durchführen, indem Sie die Vorteile von Microsoft LINQ to SQL nutzen.
In diesem Tutorial erstellen wir eine einfache Movie-Datenbankanwendung. Wir beginnen damit, die Movie-Datenbankanwendung auf die schnellste und einfachste Weise zu erstellen. Wir führen alle unsere Datenzugriffe direkt von unserem Verantwortlichen aus.
Als Nächstes erfahren Sie, wie Sie das Repositorymuster verwenden. Die Verwendung des Repositorymusters erfordert etwas mehr Arbeit. Der Vorteil dieses Musters besteht jedoch darin, dass Sie Anwendungen erstellen können, die an Änderungen angepasst werden können und leicht getestet werden können.
Was ist eine Modellklasse?
Ein MVC-Modell enthält die gesamte Anwendungslogik, die nicht in einer MVC-Ansicht oder einem MVC-Controller enthalten ist. Insbesondere enthält ein MVC-Modell ihre gesamte Anwendungsgeschäfts- und Datenzugriffslogik.
Sie können eine Vielzahl verschiedener Technologien verwenden, um Ihre Datenzugriffslogik zu implementieren. Beispielsweise können Sie Ihre Datenzugriffsklassen mit den Klassen Microsoft Entity Framework, NHibernate, Subsonic oder ADO.NET erstellen.
In diesem Tutorial verwende ich LINQ to SQL, um die Datenbank abzufragen und zu aktualisieren. LINQ to SQL bietet Ihnen eine sehr einfache Methode zur Interaktion mit einer Microsoft SQL Server-Datenbank. Es ist jedoch wichtig zu verstehen, dass das ASP.NET MVC-Framework in keiner Weise an LINQ to SQL gebunden ist. ASP.NET MVC ist mit jeder Datenzugriffstechnologie kompatibel.
Erstellen einer Filmdatenbank
In diesem Tutorial erstellen wir eine einfache Movie-Datenbankanwendung, um zu veranschaulichen, wie Sie Modellklassen erstellen können. Der erste Schritt besteht darin, eine neue Datenbank zu erstellen. Klicken Sie im fenster Projektmappen-Explorer mit der rechten Maustaste auf den Ordner App_Data, und wählen Sie die Menüoption Hinzufügen, Neues Element aus. Wählen Sie die Vorlage SQL Server Datenbank aus, geben Sie ihr den Namen MoviesDB.mdf, und klicken Sie auf die Schaltfläche Hinzufügen (siehe Abbildung 1).
Abbildung 01: Hinzufügen einer neuen SQL Server Datenbank (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Nachdem Sie die neue Datenbank erstellt haben, können Sie die Datenbank öffnen, indem Sie im Ordner App_Data auf die Datei MoviesDB.mdf doppelklicken. Durch Doppelklicken auf die Datei MoviesDB.mdf wird das Fenster Server Explorer geöffnet (siehe Abbildung 2).
Das Fenster Server Explorer wird bei Verwendung von Visual Web Developer als Datenbankfenster Explorer bezeichnet.
Abbildung 02: Verwenden des Fensters "Server Explorer" (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Wir müssen unserer Datenbank eine Tabelle hinzufügen, die unsere Filme darstellt. Klicken Sie mit der rechten Maustaste auf den Ordner Tabellen, und wählen Sie die Menüoption Neue Tabelle hinzufügen aus. Wenn Sie diese Menüoption auswählen, wird die Designer Tabelle geöffnet (siehe Abbildung 3).
Abbildung 03: Die tabelle Designer (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Wir müssen der Datenbanktabelle die folgenden Spalten hinzufügen:
Spaltenname | Datentyp | NULL-Werte zulassen |
---|---|---|
Id | Int | False |
Titel | Nvarchar(200) | False |
Regisseur | Nvarchar(50) | False |
Sie müssen zwei besondere Dinge für die Id-Spalte ausführen. Zunächst müssen Sie die Id-Spalte als Primärschlüsselspalte markieren, indem Sie die Spalte im Designer Tabelle auswählen und auf das Symbol eines Schlüssels klicken. LINQ to SQL erfordert, dass Sie Ihre Primärschlüsselspalten angeben, wenn Sie Einfügevorgänge oder Aktualisierungen für die Datenbank ausführen.
Als Nächstes müssen Sie die Id-Spalte als Identitätsspalte markieren, indem Sie der Is Identity-Eigenschaft den Wert Ja zuweisen (siehe Abbildung 3). Eine Identitätsspalte ist eine Spalte, der automatisch eine neue Nummer zugewiesen wird, wenn Sie einer Tabelle eine neue Datenzeile hinzufügen.
Nachdem Sie diese Änderungen vorgenommen haben, speichern Sie die Tabelle mit dem Namen tblMovie. Sie können die Tabelle speichern, indem Sie auf die Schaltfläche Speichern klicken.
Erstellen LINQ to SQL Klassen
Unser MVC-Modell enthält LINQ to SQL Klassen, die die tblMovie-Datenbanktabelle darstellen. Die einfachste Möglichkeit zum Erstellen dieser LINQ to SQL Klassen besteht darin, mit der rechten Maustaste auf den Ordner Models zu klicken, Hinzufügen, Neues Element auszuwählen, die Vorlage LINQ to SQL Klassen auszuwählen, den Klassen den Namen Movie.dbml zu geben und auf die Schaltfläche Hinzufügen zu klicken (siehe Abbildung 4).
Abbildung 04: Erstellen LINQ to SQL Klassen (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Unmittelbar nachdem Sie die Movie LINQ to SQL-Klassen erstellt haben, wird die Objektrelationaler Designer angezeigt. Sie können Datenbanktabellen aus dem Fenster Server Explorer auf das Objektrelationaler Designer ziehen, um LINQ to SQL Klassen zu erstellen, die bestimmte Datenbanktabellen darstellen. Wir müssen die tblMovie-Datenbanktabelle dem Objektrelationaler Designer hinzufügen (siehe Abbildung 4).
Abbildung 05: Verwenden des Objektrelationaler Designer (Klicken Sie hier, um das bild in voller Größe anzuzeigen)
Standardmäßig erstellt der Objektrelationaler Designer eine Klasse mit demselben Namen wie die Datenbanktabelle, die Sie auf die Designer ziehen. Wir möchten jedoch nicht unsere Klasse tblMovie aufrufen. Klicken Sie daher im Designer auf den Namen der Klasse, und ändern Sie den Namen der Klasse in Movie.
Denken Sie schließlich daran, auf die Schaltfläche Speichern (das Bild der Diskette) zu klicken, um die LINQ to SQL Klassen zu speichern. Andernfalls werden die LINQ to SQL-Klassen nicht vom Objektrelationaler Designer generiert.
Verwenden von LINQ to SQL in einer Controlleraktion
Nachdem wir nun über unsere LINQ to SQL Klassen verfügen, können wir diese Klassen verwenden, um Daten aus der Datenbank abzurufen. In diesem Abschnitt erfahren Sie, wie Sie LINQ to SQL Klassen direkt innerhalb einer Controlleraktion verwenden. Die Liste der Filme aus der tblMovies-Datenbanktabelle wird in einer MVC-Ansicht angezeigt.
Zunächst müssen wir die HomeController-Klasse ändern. Diese Klasse finden Sie im Ordner Controller Ihrer Anwendung. Ändern Sie die Klasse so, dass sie wie die Klasse in Listing 1 aussieht.
Eintrag 1 – Controllers\HomeController.vb
<HandleError()> _
Public Class HomeController
Inherits System.Web.Mvc.Controller
Function Index()
Dim dataContext As New MovieDataContext()
Dim movies = From m In dataContext.Movies _
Select m
return View(movies)
End Function
End Class
Die Index()-Aktion in Listing 1 verwendet eine LINQ to SQL DataContext-Klasse (MovieDataContext), um die MoviesDB-Datenbank darzustellen. Die MoveDataContext-Klasse wurde vom Visual Studio-Objektrelationaler Designer generiert.
Eine LINQ-Abfrage wird für dataContext ausgeführt, um alle Filme aus der tblMovies-Datenbanktabelle abzurufen. Die Liste der Filme ist einer lokalen Variablen namens movies zugewiesen. Schließlich wird die Liste der Filme über Ansichtsdaten an die Ansicht übergeben.
Um die Filme anzuzeigen, müssen wir als Nächstes die Indexansicht ändern. Sie finden die Indexansicht im Ordner Ansichten\Home\. Aktualisieren Sie die Indexansicht so, dass sie wie die Ansicht in Listing 2 aussieht.
Eintrag 2 – Views\Home\Index.aspx
<%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="false" CodeBehind="Index.aspx.vb" Inherits="MvcApplication1.Index" %>
<%@ Import Namespace="MvcApplication1" %>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<ul>
<% For Each m As Movie In ViewData.Model%>
<li><%= m.Title %></li>
<% Next%>
</ul>
</asp:Content>
Beachten Sie, dass die geänderte Indexansicht oben in der Ansicht eine <%@ import namespace %> -Anweisung enthält. Diese Direktive importiert den Namespace MvcApplication1. Wir benötigen diesen Namespace, um mit den Modellklassen – insbesondere der Movie-Klasse – in der Ansicht zu arbeiten.
Die Ansicht in Listing 2 enthält eine For Each-Schleife, die alle durch die ViewData.Model-Eigenschaft dargestellten Elemente durchlaufen. Der Wert der Title-Eigenschaft wird für jeden Film angezeigt.
Beachten Sie, dass der Wert der ViewData.Model-Eigenschaft in ein IEnumerable umgewandelt wird. Dies ist erforderlich, um den Inhalt von ViewData.Model zu durchlaufen. Eine weitere Möglichkeit besteht darin, eine stark typisierte Ansicht zu erstellen. Wenn Sie eine stark typisierte Ansicht erstellen, wandeln Sie die ViewData.Model-Eigenschaft in einen bestimmten Typ in der CodeBehind-Klasse einer Ansicht um.
Wenn Sie die Anwendung nach dem Ändern der HomeController-Klasse und der Indexansicht ausführen, erhalten Sie eine leere Seite. Sie erhalten eine leere Seite, da in der tblMovies-Datenbanktabelle keine Filmdatensätze vorhanden sind.
Klicken Sie zum Hinzufügen von Datensätzen zur tblMovies-Datenbanktabelle im Fenster Server Explorer (Fenster Datenbank Explorer in Visual Web Developer) mit der rechten Maustaste auf die Datenbanktabelle tblMovies, und wählen Sie die Menüoption Tabellendaten anzeigen aus. Sie können Filmdatensätze mithilfe des angezeigten Rasters einfügen (siehe Abbildung 5).
Abbildung 06: Einfügen von Filmen (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Nachdem Sie der Tabelle tblMovies einige Datenbankdatensätze hinzugefügt und die Anwendung ausgeführt haben, wird die Seite in Abbildung 7 angezeigt. Alle Filmdatenbankdatensätze werden in einer Aufzählung angezeigt.
Abbildung 07: Anzeigen von Filmen mit der Indexansicht (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Verwenden des Repositorymusters
Im vorherigen Abschnitt haben wir LINQ to SQL Klassen direkt innerhalb einer Controlleraktion verwendet. Wir haben die MovieDataContext-Klasse direkt aus der Index()-Controlleraktion verwendet. Im Falle einer einfachen Anwendung ist nichts falsch daran, dies zu tun. Die direkte Arbeit mit LINQ to SQL in einer Controllerklasse führt jedoch zu Problemen, wenn Sie eine komplexere Anwendung erstellen müssen.
Die Verwendung von LINQ to SQL innerhalb einer Controllerklasse erschwert den Wechsel von Datenzugriffstechnologien in Zukunft. Beispielsweise können Sie sich entscheiden, von der Verwendung von Microsoft LINQ to SQL zur Verwendung von Microsoft Entity Framework als Datenzugriffstechnologie zu wechseln. In diesem Fall müssen Sie jeden Controller, der auf die Datenbank in Ihrer Anwendung zugreift, umschreiben.
Die Verwendung von LINQ to SQL innerhalb einer Controllerklasse erschwert auch das Erstellen von Komponententests für Ihre Anwendung. Normalerweise möchten Sie beim Ausführen von Komponententests nicht mit einer Datenbank interagieren. Sie möchten Ihre Komponententests verwenden, um Ihre Anwendungslogik und nicht Ihren Datenbankserver zu testen.
Um eine MVC-Anwendung zu erstellen, die besser an zukünftige Änderungen angepasst werden kann und leichter getestet werden kann, sollten Sie das Repositorymuster in Betracht ziehen. Wenn Sie das Repositorymuster verwenden, erstellen Sie eine separate Repositoryklasse, die ihre gesamte Datenbankzugriffslogik enthält.
Wenn Sie die Repositoryklasse erstellen, erstellen Sie eine Schnittstelle, die alle von der Repositoryklasse verwendeten Methoden darstellt. Innerhalb Ihrer Controller schreiben Sie Ihren Code für die Schnittstelle und nicht für das Repository. Auf diese Weise können Sie das Repository in Zukunft mithilfe verschiedener Datenzugriffstechnologien implementieren.
Die Schnittstelle in Listing 3 heißt IMovieRepository und stellt eine einzelne Methode namens ListAll() dar.
Eintrag 3 – Models\IMovieRepository.vb
Public Interface IMovieRepository
Function ListAll() As IList(Of Movie)
End Interface
Die Repositoryklasse in Listing 4 implementiert die IMovieRepository-Schnittstelle. Beachten Sie, dass sie eine Methode mit dem Namen ListAll() enthält, die der von der IMovieRepository-Schnittstelle erforderlichen Methode entspricht.
Eintrag 4 – Models\MovieRepository.vb
Public Class MovieRepository Implements IMovieRepository
Private _dataContext As MovieDataContext
Public Sub New()
_dataContext = New MovieDataContext()
End Sub
Public Function ListAll() As IList(Of Movie) Implements IMovieRepository.ListAll
Dim movies = From m In _dataContext.Movies _
Select m
Return movies.ToList()
End Function
End Class
Schließlich verwendet die MoviesController-Klasse in Listing 5 das Repository-Muster. LINQ to SQL Klassen werden nicht mehr direkt verwendet.
Auflistung 5 – Controllers\MoviesController.vb
using System.Web.Mvc;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
Public Class MoviesController
Inherits System.Web.Mvc.Controller
Private _repository As IMovieRepository
Sub New()
Me.New(New MovieRepository())
End Sub
Sub New(ByVal repository As IMovieRepository)
_repository = repository
End Sub
Function Index()
Return View(_repository.ListAll())
End Function
End Class
}
Beachten Sie, dass die MoviesController-Klasse in Listing 5 über zwei Konstruktoren verfügt. Der erste Konstruktor, der parameterlose Konstruktor, wird aufgerufen, wenn Ihre Anwendung ausgeführt wird. Dieser Konstruktor erstellt eine instance der MovieRepository-Klasse und übergibt sie an den zweiten Konstruktor.
Der zweite Konstruktor verfügt über einen einzelnen Parameter: einen IMovieRepository-Parameter. Dieser Konstruktor weist einfach den Wert des Parameters einem Feld auf Klassenebene mit dem Namen _repository zu.
Die MoviesController-Klasse nutzt ein Softwareentwurfsmuster, das als Dependency Injection-Muster bezeichnet wird. Insbesondere wird etwas verwendet, das als Konstruktorabhängigkeitsinjektion bezeichnet wird. Weitere Informationen zu diesem Muster finden Sie im folgenden Artikel von Martin Fowler:
http://martinfowler.com/articles/injection.html
Beachten Sie, dass der gesamte Code in der MoviesController-Klasse (mit Ausnahme des ersten Konstruktors) mit der IMovieRepository-Schnittstelle und nicht mit der eigentlichen MovieRepository-Klasse interagiert. Der Code interagiert mit einer abstrakten Schnittstelle anstelle einer konkreten Implementierung der Schnittstelle.
Wenn Sie die von der Anwendung verwendete Datenzugriffstechnologie ändern möchten, können Sie einfach die IMovieRepository-Schnittstelle mit einer Klasse implementieren, die die alternative Datenbankzugriffstechnologie verwendet. Sie können beispielsweise eine EntityFrameworkMovieRepository-Klasse oder eine SubSonicMovieRepository-Klasse erstellen. Da die Controllerklasse für die Schnittstelle programmiert ist, können Sie eine neue Implementierung von IMovieRepository an die Controllerklasse übergeben, und die Klasse würde weiterhin funktionieren.
Wenn Sie außerdem die MoviesController-Klasse testen möchten, können Sie eine gefälschte Filmrepositoryklasse an den MoviesController übergeben. Sie können die IMovieRepository-Klasse mit einer Klasse implementieren, die nicht tatsächlich auf die Datenbank zugreift, aber alle erforderlichen Methoden der IMovieRepository-Schnittstelle enthält. Auf diese Weise können Sie komponententests für die MoviesController-Klasse ausführen, ohne tatsächlich auf eine echte Datenbank zuzugreifen.
Zusammenfassung
Das Ziel dieses Tutorials war es, zu veranschaulichen, wie Sie MVC-Modellklassen erstellen können, indem Sie microsoft LINQ to SQL nutzen. Wir haben zwei Strategien zum Anzeigen von Datenbankdaten in einer ASP.NET MVC-Anwendung untersucht. Zunächst haben wir LINQ to SQL Klassen erstellt und die Klassen direkt innerhalb einer Controlleraktion verwendet. Mithilfe LINQ to SQL Klassen innerhalb eines Controllers können Sie Datenbankdaten schnell und einfach in einer MVC-Anwendung anzeigen.
Als Nächstes haben wir einen etwas schwierigeren, aber definitiv tugendhafteren Pfad für die Anzeige von Datenbankdaten untersucht. Wir haben das Repositorymuster genutzt und die gesamte Datenbankzugriffslogik in einer separaten Repositoryklasse platziert. In unserem Controller haben wir den gesamten Code für eine Schnittstelle anstelle einer konkreten Klasse geschrieben. Der Vorteil des Repositorymusters besteht darin, dass es uns ermöglicht, die Datenbankzugriffstechnologien in Zukunft einfach zu ändern und unsere Controllerklassen einfach zu testen.