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 Erik Reitan
In dieser Lernprogrammreihe lernen Sie die Grundlagen der Erstellung einer ASP.NET Web Forms-Anwendung mithilfe von ASP.NET 4.5 und Microsoft Visual Studio Express 2013 für Web kennen. Für diese Lernprogrammreihe steht ein Visual Studio 2013-Projekt mit C#-Quellcode zur Verfügung.
In diesem Lernprogramm wird das Erstellen, Zugreifen und Überprüfen von Daten aus einer Datenbank mithilfe von ASP.NET Web Forms und Entity Framework Code First beschrieben. Dieses Lernprogramm baut auf dem vorherigen Lernprogramm "Projekt erstellen" auf und ist Teil der Lernprogrammreihe Wingtip Toy Store. Wenn Sie dieses Lernprogramm abgeschlossen haben, haben Sie eine Gruppe von Datenzugriffsklassen erstellt, die sich im Ordner "Modelle" des Projekts befinden.
Was Sie lernen:
- Erstellen der Datenmodelle
- Datenbank initialisieren und seeden.
- Aktualisieren und Konfigurieren der Anwendung zur Unterstützung der Datenbank
Dies sind die im Lernprogramm eingeführten Features:
- Entity Framework-Code zuerst
- LocalDB
- Datenanmerkungen
Erstellen der Datenmodelle
Entity Framework ist ein objektrelationales Zuordnungsframework (ORM). Sie können mit relationalen Daten als Objekte arbeiten, wodurch die meisten Datenzugriffscode, den Sie normalerweise schreiben müssen, wegfallen. Mithilfe von Entity Framework können Sie Abfragen mithilfe von LINQ ausstellen und daten dann als stark typierte Objekte abrufen und bearbeiten. LINQ stellt Muster zum Abfragen und Aktualisieren von Daten bereit. Mithilfe von Entity Framework können Sie sich auf das Erstellen der restlichen Anwendung konzentrieren, anstatt sich auf die Grundlagen des Datenzugriffs zu konzentrieren. Später in dieser Lernprogrammreihe zeigen wir Ihnen, wie Sie die Daten zum Auffüllen von Navigations- und Produktabfragen verwenden.
Entity Framework unterstützt ein Entwicklungsparadigma namens Code First. Mit Code First können Sie Ihre Datenmodelle mithilfe von Klassen definieren. Eine Klasse ist ein Konstrukt, mit dem Sie eigene benutzerdefinierte Typen erstellen können, indem Sie Variablen anderer Typen, Methoden und Ereignisse gruppieren. Sie können Klassen einer vorhandenen Datenbank zuordnen oder sie zum Generieren einer Datenbank verwenden. In diesem Lernprogramm erstellen Sie die Datenmodelle, indem Sie Datenmodellklassen schreiben. Anschließend lassen Sie Entity Framework die Datenbank direkt aus diesen neuen Klassen erstellen.
Zunächst erstellen Sie die Entitätsklassen, die die Datenmodelle für die Webanwendung definieren. Anschließend erstellen Sie eine Kontextklasse, die die Entitätsklassen verwaltet und Datenzugriff auf die Datenbank bereitstellt. Außerdem erstellen Sie eine Initialisierungsklasse, die Sie zum Auffüllen der Datenbank verwenden.
Entity Framework und Verweise
Entity Framework ist standardmäßig enthalten, wenn Sie eine neue ASP.NET Webanwendung mithilfe der Webformularvorlage erstellen. Entity Framework kann als NuGet-Paket installiert, deinstalliert und aktualisiert werden.
Dieses NuGet-Paket enthält die folgenden Laufzeitassemblys in Ihrem Projekt:
- EntityFramework.dll – Der gesamte übliche Laufzeitcode, der von Entity Framework verwendet wird
- EntityFramework.SqlServer.dll – Der Microsoft SQL Server-Anbieter für Entity Framework
Entitätsklassen
Die Klassen, die Sie zum Definieren des Schemas der Daten erstellen, werden als Entitätsklassen bezeichnet. Wenn Sie mit dem Datenbankentwurf noch nicht fertig sind, sollten Sie sich die Entitätsklassen als Tabellendefinitionen einer Datenbank vorstellen. Jede Eigenschaft in der Klasse gibt eine Spalte in der Tabelle der Datenbank an. Diese Klassen stellen eine einfache, objektrelationale Schnittstelle zwischen objektorientiertem Code und der relationalen Tabellenstruktur der Datenbank bereit.
In diesem Lernprogramm beginnen Sie, indem Sie einfache Entitätsklassen hinzufügen, die schemas für Produkte und Kategorien darstellen. Die Produktklasse enthält Definitionen für jedes Produkt. Der Name jedes Mitglieds der Produktklasse ist ProductID, ProductName, Description, ImagePath, UnitPrice, CategoryID und Category. Die Kategorieklasse enthält Definitionen für jede Kategorie, zu der ein Produkt gehören kann, z. B. Auto, Boot oder Flugzeug. Der Name jedes der Mitglieder der Kategorieklasse wird CategoryID, CategoryName, Description und Products lauten. Jedes Produkt gehört zu einer der Kategorien. Diese Entitätsklassen werden dem vorhandenen Ordner "Models" des Projekts hinzugefügt.
Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Ordner "Modelle", und wählen Sie dann "Hinzufügen ->Neues Element" aus.
Das Dialogfeld Neues Element hinzufügen wird angezeigt.
Wählen Sie unter Visual C# im Bereich "Installiert " auf der linken Seite " Code" aus.
Wählen Sie " Klasse " im mittleren Bereich aus, und nennen Sie diese neue Klasse Product.cs.
Klicken Sie auf Hinzufügen.
Die neue Klassendatei wird im Editor angezeigt.Ersetzen Sie den Standardcode durch den folgenden Code:
using System.ComponentModel.DataAnnotations; namespace WingtipToys.Models { public class Product { [ScaffoldColumn(false)] public int ProductID { get; set; } [Required, StringLength(100), Display(Name = "Name")] public string ProductName { get; set; } [Required, StringLength(10000), Display(Name = "Product Description"), DataType(DataType.MultilineText)] public string Description { get; set; } public string ImagePath { get; set; } [Display(Name = "Price")] public double? UnitPrice { get; set; } public int? CategoryID { get; set; } public virtual Category Category { get; set; } } }Erstellen Sie eine weitere Klasse, indem Sie die Schritte 1 bis 4 wiederholen, nennen Sie jedoch die neue Klasse Category.cs , und ersetzen Sie den Standardcode durch den folgenden Code:
using System.Collections.Generic; using System.ComponentModel.DataAnnotations; namespace WingtipToys.Models { public class Category { [ScaffoldColumn(false)] public int CategoryID { get; set; } [Required, StringLength(100), Display(Name = "Name")] public string CategoryName { get; set; } [Display(Name = "Product Description")] public string Description { get; set; } public virtual ICollection<Product> Products { get; set; } } }
Wie bereits erwähnt, stellt die Category Klasse die Art des Produkts dar, das die Anwendung verkaufen soll (z. B. "Cars", "Boats", "Rockets" usw.), und die Product Klasse stellt die einzelnen Produkte (Spielzeug) in der Datenbank dar. Jede Instanz eines Product Objekts entspricht einer Zeile in einer relationalen Datenbanktabelle, und jede Eigenschaft der Product-Klasse wird einer Spalte in der relationalen Datenbanktabelle zugeordnet. Später in diesem Lernprogramm überprüfen Sie die Produktdaten, die in der Datenbank enthalten sind.
Datenanmerkungen
Möglicherweise haben Sie bemerkt, dass bestimmte Member der Klassen Attribute enthalten, die Details zum Member angeben, z. B. [ScaffoldColumn(false)]. Hierbei handelt es sich um Datenanmerkungen. Die Datenanmerkungsattribute können beschreiben, wie Benutzereingaben für dieses Element überprüft werden, formatierungen dafür angegeben werden und wie sie modelliert werden, wenn die Datenbank erstellt wird.
Context-Klasse
Um mit der Verwendung der Klassen für den Datenzugriff zu beginnen, müssen Sie eine Kontextklasse definieren. Wie bereits erwähnt, verwaltet die Kontextklasse die Entitätsklassen (z. B. die Product Klasse und die Category Klasse) und bietet Datenzugriff auf die Datenbank.
Diese Prozedur fügt dem Ordner "Models " eine neue C#-Kontextklasse hinzu.
Klicken Sie mit der rechten Maustaste auf den Ordner "Modelle", und wählen Sie dann "Hinzufügen ->Neues Element" aus.
Das Dialogfeld Neues Element hinzufügen wird angezeigt.Wählen Sie " Klasse " im mittleren Bereich aus, nennen Sie sie ProductContext.cs , und klicken Sie auf "Hinzufügen".
Ersetzen Sie den in der Klasse enthaltenen Standardcode durch den folgenden Code:
using System.Data.Entity; namespace WingtipToys.Models { public class ProductContext : DbContext { public ProductContext() : base("WingtipToys") { } public DbSet<Category> Categories { get; set; } public DbSet<Product> Products { get; set; } } }
Dieser Code fügt den System.Data.Entity Namespace hinzu, sodass Sie Zugriff auf alle Kernfunktionen von Entity Framework haben, die die Funktion zum Abfragen, Einfügen, Aktualisieren und Löschen von Daten enthält, indem Sie mit stark typierten Objekten arbeiten.
Die ProductContext Klasse stellt den Entity Framework-Produktdatenbankkontext dar, der das Abrufen, Speichern und Aktualisieren Product von Klasseninstanzen in der Datenbank behandelt. Die ProductContext Klasse leitet sich von der DbContext Basisklasse ab, die von Entity Framework bereitgestellt wird.
Initialisierungsklasse
Sie müssen einige benutzerdefinierte Logik ausführen, um die Datenbank beim ersten Verwenden des Kontexts zu initialisieren. Dadurch können Startdaten der Datenbank hinzugefügt werden, sodass Sie Produkte und Kategorien sofort anzeigen können.
Mit dieser Prozedur wird dem Ordner "Models " eine neue C#-Initialisiererklasse hinzugefügt.
Erstellen Sie einen anderen
Classim Ordner "Models ", und nennen Sie ihn ProductDatabaseInitializer.cs.Ersetzen Sie den in der Klasse enthaltenen Standardcode durch den folgenden Code:
using System.Collections.Generic; using System.Data.Entity; namespace WingtipToys.Models { public class ProductDatabaseInitializer : DropCreateDatabaseIfModelChanges<ProductContext> { protected override void Seed(ProductContext context) { GetCategories().ForEach(c => context.Categories.Add(c)); GetProducts().ForEach(p => context.Products.Add(p)); } private static List<Category> GetCategories() { var categories = new List<Category> { new Category { CategoryID = 1, CategoryName = "Cars" }, new Category { CategoryID = 2, CategoryName = "Planes" }, new Category { CategoryID = 3, CategoryName = "Trucks" }, new Category { CategoryID = 4, CategoryName = "Boats" }, new Category { CategoryID = 5, CategoryName = "Rockets" }, }; return categories; } private static List<Product> GetProducts() { var products = new List<Product> { new Product { ProductID = 1, ProductName = "Convertible Car", Description = "This convertible car is fast! The engine is powered by a neutrino based battery (not included)." + "Power it up and let it go!", ImagePath="carconvert.png", UnitPrice = 22.50, CategoryID = 1 }, new Product { ProductID = 2, ProductName = "Old-time Car", Description = "There's nothing old about this toy car, except it's looks. Compatible with other old toy cars.", ImagePath="carearly.png", UnitPrice = 15.95, CategoryID = 1 }, new Product { ProductID = 3, ProductName = "Fast Car", Description = "Yes this car is fast, but it also floats in water.", ImagePath="carfast.png", UnitPrice = 32.99, CategoryID = 1 }, new Product { ProductID = 4, ProductName = "Super Fast Car", Description = "Use this super fast car to entertain guests. Lights and doors work!", ImagePath="carfaster.png", UnitPrice = 8.95, CategoryID = 1 }, new Product { ProductID = 5, ProductName = "Old Style Racer", Description = "This old style racer can fly (with user assistance). Gravity controls flight duration." + "No batteries required.", ImagePath="carracer.png", UnitPrice = 34.95, CategoryID = 1 }, new Product { ProductID = 6, ProductName = "Ace Plane", Description = "Authentic airplane toy. Features realistic color and details.", ImagePath="planeace.png", UnitPrice = 95.00, CategoryID = 2 }, new Product { ProductID = 7, ProductName = "Glider", Description = "This fun glider is made from real balsa wood. Some assembly required.", ImagePath="planeglider.png", UnitPrice = 4.95, CategoryID = 2 }, new Product { ProductID = 8, ProductName = "Paper Plane", Description = "This paper plane is like no other paper plane. Some folding required.", ImagePath="planepaper.png", UnitPrice = 2.95, CategoryID = 2 }, new Product { ProductID = 9, ProductName = "Propeller Plane", Description = "Rubber band powered plane features two wheels.", ImagePath="planeprop.png", UnitPrice = 32.95, CategoryID = 2 }, new Product { ProductID = 10, ProductName = "Early Truck", Description = "This toy truck has a real gas powered engine. Requires regular tune ups.", ImagePath="truckearly.png", UnitPrice = 15.00, CategoryID = 3 }, new Product { ProductID = 11, ProductName = "Fire Truck", Description = "You will have endless fun with this one quarter sized fire truck.", ImagePath="truckfire.png", UnitPrice = 26.00, CategoryID = 3 }, new Product { ProductID = 12, ProductName = "Big Truck", Description = "This fun toy truck can be used to tow other trucks that are not as big.", ImagePath="truckbig.png", UnitPrice = 29.00, CategoryID = 3 }, new Product { ProductID = 13, ProductName = "Big Ship", Description = "Is it a boat or a ship. Let this floating vehicle decide by using its " + "artifically intelligent computer brain!", ImagePath="boatbig.png", UnitPrice = 95.00, CategoryID = 4 }, new Product { ProductID = 14, ProductName = "Paper Boat", Description = "Floating fun for all! This toy boat can be assembled in seconds. Floats for minutes!" + "Some folding required.", ImagePath="boatpaper.png", UnitPrice = 4.95, CategoryID = 4 }, new Product { ProductID = 15, ProductName = "Sail Boat", Description = "Put this fun toy sail boat in the water and let it go!", ImagePath="boatsail.png", UnitPrice = 42.95, CategoryID = 4 }, new Product { ProductID = 16, ProductName = "Rocket", Description = "This fun rocket will travel up to a height of 200 feet.", ImagePath="rocket.png", UnitPrice = 122.95, CategoryID = 5 } }; return products; } } }
Wie Sie im obigen Code sehen können, wird die Seed Eigenschaft überschrieben und festgelegt, wenn die Datenbank erstellt und initialisiert wird. Wenn die Seed Eigenschaft festgelegt wird, werden die Werte aus den Kategorien und Produkten verwendet, um die Datenbank aufzufüllen. Wenn Sie versuchen, die Seeddaten zu aktualisieren, indem Sie den obigen Code ändern, nachdem die Datenbank erstellt wurde, werden beim Ausführen der Webanwendung keine Aktualisierungen angezeigt. Der Grund hierfür ist, dass der obige Code eine Implementierung der DropCreateDatabaseIfModelChanges Klasse verwendet, um zu erkennen, ob sich das Modell (Schema) geändert hat, bevor die Seeddaten zurückgesetzt werden. Wenn an den Category Klassen und Product Entitätsklassen keine Änderungen vorgenommen werden, wird die Datenbank nicht mit den Seeddaten erneut initialisiert.
Hinweis
Wenn Sie möchten, dass die Datenbank jedes Mal neu erstellt wird, wenn Sie die Anwendung ausgeführt haben, können Sie die DropCreateDatabaseAlways Klasse anstelle der DropCreateDatabaseIfModelChanges Klasse verwenden. Verwenden Sie für diese Lernprogrammreihe jedoch die DropCreateDatabaseIfModelChanges Klasse.
An diesem Punkt in diesem Lernprogramm haben Sie einen Ordner "Models" mit vier neuen Klassen und einer Standardklasse:
Konfigurieren der Anwendung für die Verwendung des Datenmodells
Nachdem Sie nun die Klassen erstellt haben, die die Daten darstellen, müssen Sie die Anwendung so konfigurieren, dass sie die Klassen verwendet. In der Datei "Global.asax " fügen Sie Code hinzu, der das Modell initialisiert. In der Web.config-Datei fügen Sie Informationen hinzu, die der Anwendung mitteilen, welche Datenbank Sie zum Speichern der durch die neuen Datenklassen dargestellten Daten verwenden. Die Datei "Global.asax " kann zum Behandeln von Anwendungsereignissen oder -methoden verwendet werden. Mit der Web.config-Datei können Sie die Konfiguration Ihrer ASP.NET Webanwendung steuern.
Aktualisieren der Datei "Global.asax"
Um die Datenmodelle beim Start der Anwendung zu initialisieren, aktualisieren Sie den Application_Start Handler in der Global.asax.cs Datei.
Hinweis
Im Projektmappen-Explorer können Sie entweder die Datei "Global.asax " oder die Global.asax.cs Datei auswählen, um die Global.asax.cs Datei zu bearbeiten.
Fügen Sie der Methode in der
Application_Startdatei Global.asax.cs den folgenden gelb hervorgehobenen Code hinzu.using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Optimization; using System.Web.Routing; using System.Web.Security; using System.Web.SessionState; using System.Data.Entity; using WingtipToys.Models; namespace WingtipToys { public class Global : HttpApplication { void Application_Start(object sender, EventArgs e) { // Code that runs on application startup RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); // Initialize the product database. Database.SetInitializer(new ProductDatabaseInitializer()); } } }
Hinweis
Ihr Browser muss HTML5 unterstützen, um den gelb hervorgehobenen Code anzuzeigen, wenn sie diese Lernprogrammreihe in einem Browser anzeigen.
Wie im obigen Code gezeigt, gibt die Anwendung beim Start der Anwendung den Initialisierer an, der beim ersten Zugriff auf die Daten ausgeführt wird. Die beiden zusätzlichen Namespaces sind erforderlich, um auf das Database Objekt und das ProductDatabaseInitializer Objekt zuzugreifen.
Ändern der Web.Config-Datei
Obwohl Entity Framework Code First eine Datenbank für Sie an einem Standardspeicherort generiert, wenn die Datenbank mit Seeddaten aufgefüllt wird, erhalten Sie durch Hinzufügen eigener Verbindungsinformationen zu Ihrer Anwendung die Kontrolle über den Datenbankspeicherort. Sie geben diese Datenbankverbindung mithilfe einer Verbindungszeichenfolge in der Web.config Datei der Anwendung im Stammverzeichnis des Projekts an. Durch Hinzufügen einer neuen Verbindungszeichenfolge können Sie den Speicherort der Datenbank (wingtiptoys.mdf) so leiten, dass sie im Datenverzeichnis der Anwendung (App_Data) erstellt wird, anstatt den Standardspeicherort. Wenn Sie diese Änderung vornehmen, können Sie die Datenbankdatei später in diesem Lernprogramm suchen und prüfen.
Suchen und öffnen Sie im Projektmappen-Explorer die Datei Web.config.
Fügen Sie die in Gelb hervorgehobene Verbindungszeichenfolge zum
<connectionStrings>Abschnitt der Web.config Datei wie folgt hinzu:<connectionStrings> <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-WingtipToys-20131119102907.mdf;Initial Catalog=aspnet-WingtipToys-20131119102907;Integrated Security=True" providerName="System.Data.SqlClient" /> <add name="WingtipToys" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\wingtiptoys.mdf;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings>
Wenn die Anwendung zum ersten Mal ausgeführt wird, erstellt sie die Datenbank an dem speicherort, der durch die Verbindungszeichenfolge angegeben wird. Aber bevor wir die Anwendung ausführen, erstellen wir sie zuerst.
Erstellen der Anwendung
Um sicherzustellen, dass alle Klassen und Änderungen an Ihrer Webanwendung funktionieren, sollten Sie die Anwendung erstellen.
Wählen Sie im Menü "Debuggen " die Option "WingtipToys erstellen" aus.
Das Ausgabefenster wird angezeigt, und wenn alles gut funktioniert hat, wird eine Meldung "Erfolgreich " angezeigt.
Wenn ein Fehler auftritt, überprüfen Sie die obigen Schritte erneut. Die Informationen im Ausgabefenster geben an, welche Datei ein Problem hat und wo in der Datei eine Änderung erforderlich ist. Mit diesen Informationen können Sie ermitteln, welcher Teil der obigen Schritte in Ihrem Projekt überprüft und behoben werden muss.
Zusammenfassung
In diesem Lernprogramm der Reihe haben Sie das Datenmodell erstellt und den Code hinzugefügt, der zum Initialisieren und Füllen der Datenbank verwendet werden wird. Sie haben die Anwendung auch so konfiguriert, dass sie die Datenmodelle verwendet, wenn die Anwendung ausgeführt wird.
Im nächsten Lernprogramm aktualisieren Sie die Benutzeroberfläche, fügen Navigation hinzu und rufen Daten aus der Datenbank ab. Dies führt dazu, dass die Datenbank automatisch basierend auf den Entitätsklassen erstellt wird, die Sie in diesem Lernprogramm erstellt haben.
Zusätzliche Ressourcen
Entity Framework (Übersicht)
Leitfaden für Anfänger zum ADO.NET Entity Framework
Code First Development with Entity FrameworkCode First Relationships Fluent API
Code First Data Annotations
Produktivitätsverbesserungen für das Entity Framework