Erstellen eines Entity Framework-Datenmodells für eine ASP.NET MVC-Anwendung (1 von 10)
Von Tom Dykstra
Hinweis
Eine neuere Version dieser Lernprogrammreihe ist für Visual Studio 2013, Entity Framework 6 und MVC 5 verfügbar.
Die Contoso University-Beispielwebanwendung veranschaulicht, wie ASP.NET MVC 4-Anwendungen mithilfe von Entity Framework 5 und Visual Studio 2012 erstellt werden. Bei der Beispiel-App handelt es sich um eine Website für die fiktive Contoso University. Sie enthält Funktionen wie die Zulassung von Studenten, die Erstellung von Kursen und Aufgaben von Dozenten. In dieser Lernprogrammreihe wird erläutert, wie Sie die Contoso University-Beispielanwendung erstellen.
Code First
Es gibt drei Möglichkeiten zum Arbeiten mit Daten im Entity Framework: Database First, Model First und Code First. Dieses Lernprogramm richtet sich an Code First. Informationen zu den Unterschieden zwischen diesen Workflows und Anleitungen zum Auswählen des besten für Ihr Szenarios finden Sie unter Entity Framework Development Workflows.
MVC
Die Beispielanwendung basiert auf ASP.NET MVC. Wenn Sie lieber mit dem ASP.NET Web Forms-Modell arbeiten möchten, lesen Sie die Lernprogrammreihe "Model Binding" und "Web Forms " und ASP.NET Data Access Content Map.
Softwareversionen
Im Lernprogramm gezeigt Funktioniert auch mit Windows 8 Windows 7 Visual Studio 2012 Visual Studio 2012 Express for Web. Dies wird automatisch vom Windows Azure SDK installiert, wenn Sie noch nicht über VS 2012 oder VS 2012 Express for Web verfügen. Visual Studio 2013 sollte funktionieren, aber das Lernprogramm wurde nicht damit getestet, und einige Menüauswahlen und Dialogfelder unterscheiden sich. Die VS 2013-Version des Windows Azure SDK ist für die Windows Azure-Bereitstellung erforderlich. .NET 4.5 Die meisten der angezeigten Features funktionieren in .NET 4, aber einige werden nicht. Die Enumerationsunterstützung in EF erfordert z. B. .NET 4.5. Entity Framework 5 Windows Azure SDK 2.1 Wenn Sie die Windows Azure-Bereitstellungsschritte überspringen, benötigen Sie das SDK nicht. Wenn eine neue Version des SDK veröffentlicht wird, installiert der Link die neuere Version. In diesem Fall müssen Sie möglicherweise einige der Anweisungen an neue Ui und Features anpassen. Fragen
Wenn Sie Fragen haben, die sich nicht direkt auf das Lernprogramm beziehen, können Sie sie im Forum ASP.NET Entity Framework, dem Forum "Entity Framework" und " LINQ to Entities" veröffentlichen oder StackOverflow.com.
Danksagungen
Sehen Sie sich das letzte Lernprogramm in der Reihe an, um Bestätigungen und eine Notiz zu VB zu erfahren.
Die Contoso University-Webanwendung
Bei der Anwendung, die Sie mithilfe dieser Tutorials erstellen, handelt es sich um eine einfache Universitätswebsite.
Benutzer können Informationen zu den Studenten, Kursen und Dozenten abrufen. Nachfolgend werden einige Anzeigen dargestellt, die erstellt werden sollen.
Der Benutzeroberflächenstil dieser Website orientiert sich an den integrierten Vorlagen, sodass Sie mit dieses Tutorial hauptsächlich auf die Verwendung von Entity Framework konzentriert.
Voraussetzungen
Die Anweisungen und Screenshots in diesem Lernprogramm gehen davon aus, dass Sie Visual Studio 2012 oder Visual Studio 2012 Express für Web verwenden, wobei das neueste Update und das Azure SDK für .NET ab Juli 2013 installiert sind. Sie können all dies mit dem folgenden Link abrufen:
Azure SDK für .NET (Visual Studio 2012)
Wenn Sie Visual Studio installiert haben, installiert der obige Link alle fehlenden Komponenten. Wenn Sie nicht über Visual Studio verfügen, installiert der Link Visual Studio 2012 Express for Web. Sie können Visual Studio 2013 verwenden, einige der erforderlichen Verfahren und Bildschirme unterscheiden sich jedoch.
Erstellen einer MVC-Webanwendung
Öffnen Sie Visual Studio, und erstellen Sie ein neues C#-Projekt namens "ContosoUniversity" mithilfe der ASP.NET MVC 4-Webanwendungsvorlage . Stellen Sie sicher, dass Sie .NET Framework 4.5 verwenden (Sie verwenden enum
Eigenschaften und benötigen .NET 4.5).
Wählen Sie im Dialogfeld "Neues ASP.NET MVC 4-Projekt " die Internetanwendungsvorlage aus.
Lassen Sie das Razor-Ansichtsmodul aktiviert, und lassen Sie das Kontrollkästchen "Komponententestprojekt erstellen" deaktiviert.
Klicken Sie auf OK.
Einrichten des Websiteformats
Sie können das Websitemenü, das Layout und die Startseite über einige Änderungen einrichten.
Öffnen Sie Views\Shared\_Layout.cshtml, und ersetzen Sie den Inhalt der Datei durch den folgenden Code. Die Änderungen werden hervorgehoben.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title - Contoso University</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<header>
<div class="content-wrapper">
<div class="float-left">
<p class="site-title">@Html.ActionLink("Contoso University", "Index", "Home")</p>
</div>
<div class="float-right">
<section id="login">
@Html.Partial("_LoginPartial")
</section>
<nav>
<ul id="menu">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Students", "Index", "Student")</li>
<li>@Html.ActionLink("Courses", "Index", "Course")</li>
<li>@Html.ActionLink("Instructors", "Index", "Instructor")</li>
<li>@Html.ActionLink("Departments", "Index", "Department")</li>
</ul>
</nav>
</div>
</div>
</header>
<div id="body">
@RenderSection("featured", required: false)
<section class="content-wrapper main-content clear-fix">
@RenderBody()
</section>
</div>
<footer>
<div class="content-wrapper">
<div class="float-left">
<p>© @DateTime.Now.Year - Contoso University</p>
</div>
</div>
</footer>
@Scripts.Render("~/bundles/jquery")
@RenderSection("scripts", required: false)
</body>
</html>
Durch diesen Code werden folgende Änderungen vorgenommen:
- Ersetzt die Vorlageninstanzen "Meine ASP.NET MVC-Anwendung" und "Ihr Logo hier" durch "Contoso University".
- Fügt mehrere Aktionslinks hinzu, die später im Lernprogramm verwendet werden.
Ersetzen Sie in Views\Home\Index.cshtml den Inhalt der Datei durch den folgenden Code, um die Vorlagenabsätze zu ASP.NET und MVC zu beseitigen:
@{
ViewBag.Title = "Home Page";
}
@section featured {
<section class="featured">
<div class="content-wrapper">
<hgroup class="title">
<h1>@ViewBag.Title.</h1>
<h2>@ViewBag.Message</h2>
</hgroup>
</div>
</section>
}
Ändern Sie in Controller\HomeController.cs den Wert in ViewBag.Message
der Index
Action-Methode in "Willkommen bei Contoso University!", wie im folgenden Beispiel gezeigt:
public ActionResult Index()
{
ViewBag.Message = "Welcome to Contoso University";
return View();
}
Drücken Sie STRG+F5, um die Website auszuführen. Die Startseite wird mit dem Hauptmenü angezeigt.
Erstellen des Datenmodells
Als nächstes erstellen Sie Entitätsklassen für die Contoso University-Anwendung. Sie beginnen mit den folgenden drei Entitäten:
Es besteht eine 1:n-Beziehung zwischen den Entitäten Student
und Enrollment
. Außerdem besteht eine 1:n-Beziehung zwischen den Entitäten Course
und Enrollment
. Das bedeutet, dass ein Student für beliebig viele Kurse angemeldet sein kann und sich für jeden Kurs eine beliebige Anzahl von Studenten anmelden kann.
In den folgenden Abschnitten erstellen Sie für jede dieser Entitäten eine Klasse.
Hinweis
Wenn Sie versuchen, das Projekt zu kompilieren, bevor Sie die Erstellung aller dieser Entitätsklassen abgeschlossen haben, erhalten Sie Compilerfehler.
Die Schülerentität
Erstellen Sie im Ordner "Modelle" Student.cs, und ersetzen Sie den vorhandenen Code durch den folgenden Code:
using System;
using System.Collections.Generic;
namespace ContosoUniversity.Models
{
public class Student
{
public int StudentID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
}
Die StudentID
-Eigenschaft fungiert als Primärschlüsselspalte der Datenbanktabelle, die dieser Klasse entspricht. Standardmäßig interpretiert Das Entity Framework eine Eigenschaft, die den Namen ID
oder den Klassennamen ID
als Primärschlüssel bezeichnet.
Die Enrollments
-Eigenschaft ist eine Navigationseigenschaft. Navigationseigenschaften enthalten andere Entitäten, die dieser Entität zugehörig sind. In diesem Fall enthält die Enrollments
Eigenschaft einer Student
Entität alle Entitäten, die Enrollment
mit dieser Student
Entität zusammenhängen. Anders ausgedrückt: Wenn eine bestimmte Student
Zeile in der Datenbank über zwei verknüpfte Enrollment
Zeilen verfügt (Zeilen, die den Primärschlüsselwert dieses Kursteilnehmers in ihrer StudentID
Fremdschlüsselspalte enthalten), Student
enthält die Navigationseigenschaft Enrollments
dieser Entität diese beiden Enrollment
Entitäten.
Navigationseigenschaften werden in der Regel so virtual
definiert, dass sie bestimmte Entity Framework-Funktionen nutzen können, z . B. das faule Laden. (Lazy Loading wird später im Lernprogramm zum Lesen verwandter Daten weiter unten in dieser Reihe.
Wenn eine Navigationseigenschaft mehrere Entitäten enthalten kann (wie bei m:n- oder 1:n-Beziehungen), muss dessen Typ aus einer Liste bestehen, in der Einträge hinzugefügt, gelöscht und aktualisiert werden können – z.B.: ICollection
.
Die Registrierungsentität
Erstellen Sie im Ordner Models (Modelle) die Datei Enrollment.cs, und ersetzen Sie den vorhandenen Code durch folgenden Code:
namespace ContosoUniversity.Models
{
public enum Grade
{
A, B, C, D, F
}
public class Enrollment
{
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public Grade? Grade { get; set; }
public virtual Course Course { get; set; }
public virtual Student Student { get; set; }
}
}
Die Grade-Eigenschaft ist eine Enumeration. Das Fragezeichen nach der Grade
-Typdeklaration gibt an, dass die Grade
-Eigenschaft NULL-Werte zulässt. Eine Klasse, die null ist, unterscheidet sich von einer Nullnote – Null bedeutet, dass eine Noten nicht bekannt ist oder noch nicht zugewiesen wurde.
Bei der StudentID
-Eigenschaft handelt es sich um einen Fremdschlüssel, und Student
ist die entsprechende Navigationseigenschaft. Eine Enrollment
-Entität wird einer Student
-Entität zugeordnet, damit die Eigenschaft nur eine Student
-Entität enthalten kann. Dies steht im Gegensatz zu der bereits erläuterten Student.Enrollments
-Navigationseigenschaft, die mehrere Enrollment
-Entitäten enthalten kann.
Bei der CourseID
-Eigenschaft handelt es sich um einen Fremdschlüssel, und die zugehörige Navigationseigenschaft lautet Course
. Die Enrollment
-Entität wird einer Course
-Entität zugeordnet.
Die Entität „Course“
Erstellen Sie im Ordner "Modelle" Course.cs, und ersetzen Sie den vorhandenen Code durch den folgenden Code:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace ContosoUniversity.Models
{
public class Course
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
}
Die Enrollments
-Eigenschaft ist eine Navigationseigenschaft. Course
-Entitäten können sich auf jede beliebige Anzahl von Enrollment
-Entitäten beziehen.
Wir werden mehr über die [DatabaseGenerated(DatabaseGeneratedOption) sagen. None)]-Attribut im nächsten Lernprogramm. Im Grunde können Sie über dieses Attribut den Primärschlüssel für den Kurs angeben, anstatt ihn von der Datenbank generieren zu lassen.
Erstellen des Datenbankkontexts
Die Hauptklasse, die die Entity Framework-Funktionalität für ein bestimmtes Datenmodell koordiniert, ist die Datenbankkontextklasse . Sie erstellen diese Klasse, indem Sie von der System.Data.Entity.DbContext-Klasse abgeleitet werden. Sie geben in Ihrem Code an, welche Entitäten im Datenmodell enthalten sind. Außerdem können Sie bestimmte Entity Framework-Verhalten anpassen. In diesem Projekt heißt die Klasse SchoolContext
.
Erstellen Sie einen Ordner namens DAL (für Data Access Layer). Erstellen Sie in diesem Ordner eine neue Klassendatei mit dem Namen SchoolContext.cs, und ersetzen Sie den vorhandenen Code durch den folgenden Code:
using ContosoUniversity.Models;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace ContosoUniversity.DAL
{
public class SchoolContext : DbContext
{
public DbSet<Student> Students { get; set; }
public DbSet<Enrollment> Enrollments { get; set; }
public DbSet<Course> Courses { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
Dieser Code erstellt eine DbSet-Eigenschaft für jeden Entitätssatz. In der Terminologie von Entity Framework entspricht ein Entitätssatz in der Regel einer Datenbanktabelle, und eine Entität entspricht einer Zeile in der Tabelle.
Die modelBuilder.Conventions.Remove
Anweisung in der OnModelCreating-Methode verhindert, dass Tabellennamen pluralisiert werden. Wenn Sie dies nicht tun, werden die generierten Tabellen benannt Students
, Courses
und Enrollments
. Stattdessen sind Student
die Tabellennamen , Course
und Enrollment
. Entwickler sind sich uneinig darüber, ob Tabellennamen im Plural stehen sollten oder nicht. In diesem Lernprogramm wird das Singular-Formular verwendet, aber der wichtige Punkt ist, dass Sie auswählen können, welches Formular Sie bevorzugen, indem Sie diese Codezeile einschließen oder weglassen.
SQL Server Express LocalDB
LocalDB ist eine einfache Version der SQL Server Express-Datenbank-Engine, die bei Bedarf gestartet und im Benutzermodus ausgeführt wird. LocalDB wird in einem speziellen Ausführungsmodus von SQL Server Express ausgeführt, mit dem Sie mit Datenbanken als .mdf Dateien arbeiten können. In der Regel werden LocalDB-Datenbankdateien im ordner App_Data eines Webprojekts gespeichert. Mit dem Benutzerinstanzfeature in SQL Server Express können Sie auch mit .mdf Dateien arbeiten, das Benutzerinstanzfeature ist jedoch veraltet. Daher wird LocalDB für die Arbeit mit .mdf Dateien empfohlen.
In der Regel wird SQL Server Express nicht für Produktionswebanwendungen verwendet. LocalDB wird insbesondere nicht für die Verwendung in der Produktion mit einer Webanwendung empfohlen, da sie nicht für die Verwendung mit IIS konzipiert ist.
In Visual Studio 2012 und höheren Versionen wird LocalDB standardmäßig mit Visual Studio installiert. In Visual Studio 2010 und früheren Versionen wird SQL Server Express (ohne LocalDB) standardmäßig mit Visual Studio installiert; Sie müssen sie manuell installieren, wenn Sie Visual Studio 2010 verwenden.
In diesem Lernprogramm arbeiten Sie mit LocalDB, damit die Datenbank im ordner App_Data als .mdf Datei gespeichert werden kann. Öffnen Sie die Stammdatei "Web.config", und fügen Sie der connectionStrings
Auflistung eine neue Verbindungszeichenfolge hinzu, wie im folgenden Beispiel gezeigt. (Stellen Sie sicher, dass Sie die Datei "Web.config" im Stammprojektordner. Außerdem befindet sich eine Web.config-Datei im Unterordner "Views ", den Sie nicht aktualisieren müssen.)
<add name="SchoolContext" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=ContosoUniversity;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\ContosoUniversity.mdf" providerName="System.Data.SqlClient" />
Standardmäßig sucht das Entity Framework nach einer Verbindungszeichenfolge mit dem Namen der DbContext
Klasse (SchoolContext
für dieses Projekt). Die hinzugefügte Verbindungszeichenfolge gibt eine LocalDB-Datenbank mit dem Namen ContosoUniversity.mdf im Ordner App_Data an. Weitere Informationen finden Sie unter SQL Server-Verbindungszeichenfolgen für ASP.NET Webanwendungen.
Sie müssen die Verbindungszeichenfolge nicht angeben. Wenn Sie keine Verbindungszeichenfolge bereitstellen, erstellt Entity Framework eine für Sie. Die Datenbank befindet sich jedoch möglicherweise nicht im ordner App_data Ihrer App. Informationen dazu, wo die Datenbank erstellt wird, finden Sie unter Code First to a New Database.
Die connectionStrings
Auflistung verfügt auch über eine Verbindungszeichenfolge namensDefaultConnection
, die für die Mitgliedschaftsdatenbank verwendet wird. Sie verwenden die Mitgliedschaftsdatenbank in diesem Lernprogramm nicht. Der einzige Unterschied zwischen den beiden Verbindungszeichenfolge s ist der Datenbankname und der Name-Attributwert.
Einrichten und Ausführen einer ersten Codemigration
Wenn Sie mit der Entwicklung einer Anwendung beginnen, ändert sich Ihr Datenmodell häufig, und jedes Mal, wenn das Modell geändert wird, wird es nicht mehr mit der Datenbank synchronisiert. Sie können das Entity Framework so konfigurieren, dass die Datenbank bei jeder Änderung des Datenmodells automatisch abzulegen und neu erstellt wird. Dies ist kein Problem in der frühen Entwicklung, da Testdaten einfach neu erstellt werden, aber nachdem Sie in der Produktion bereitgestellt haben, möchten Sie das Datenbankschema normalerweise aktualisieren, ohne die Datenbank zu löschen. Mit dem Migrationsfeature kann Code First die Datenbank aktualisieren, ohne sie zu löschen und erneut zu erstellen. Anfang des Entwicklungszyklus eines neuen Projekts möchten Sie möglicherweise DropCreateDatabaseIfModelChanges verwenden, um die Datenbank jedes Mal neu zu erstellen und neu zu initialisieren, wenn das Modell geändert wird. Eine, die Sie für die Bereitstellung Ihrer Anwendung vorbereiten, können Sie in den Migrationsansatz konvertieren. In diesem Lernprogramm verwenden Sie nur Migrationen. Weitere Informationen finden Sie unter Code First-Migrationen und Migrations screencast Series.
Aktivieren von Code First-Migrationen
Klicken Sie im Menü Extras auf NuGet-Paket-Manager und dann auf Paket-Manager-Konsole.
Geben Sie an der
PM>
Eingabeaufforderung den folgenden Befehl ein:enable-migrations -contexttypename SchoolContext
Dieser Befehl erstellt einen Migrationsordner im ContosoUniversity-Projekt und fügt diesen Ordner in eine Configuration.cs Datei ein, die Sie bearbeiten können, um Migrationen zu konfigurieren.
Die
Configuration
Klasse enthält eineSeed
Methode, die aufgerufen wird, wenn die Datenbank erstellt wird, und jedes Mal, wenn sie nach einer Datenmodelländerung aktualisiert wird.internal sealed class Configuration : DbMigrationsConfiguration<ContosoUniversity.Models.SchoolContext> { public Configuration() { AutomaticMigrationsEnabled = false; } protected override void Seed(ContosoUniversity.Models.SchoolContext context) { // This method will be called after migrating to the latest version. // You can use the DbSet<T>.AddOrUpdate() helper extension method // to avoid creating duplicate seed data. E.g. // // context.People.AddOrUpdate( // p => p.FullName, // new Person { FullName = "Andrew Peters" }, // new Person { FullName = "Brice Lambson" }, // new Person { FullName = "Rowan Miller" } // ); // } }
Mit dieser
Seed
Methode können Sie Testdaten nach der Erstellung oder Aktualisierung von Code First in die Datenbank einfügen.
Einrichten der Seed-Methode
Die Seed-Methode wird ausgeführt, wenn Code First-Migrationen die Datenbank erstellt und jedes Mal, wenn sie die Datenbank auf die neueste Migration aktualisiert. Der Zweck der Seed-Methode besteht darin, Es Ihnen zu ermöglichen, Daten in Ihre Tabellen einzufügen, bevor die Anwendung zum ersten Mal auf die Datenbank zugreift.
In früheren Versionen von Code First, bevor Migrationen veröffentlicht wurden, war es üblich Seed
, dass Methoden Testdaten einfügen, da bei jeder Modelländerung während der Entwicklung die Datenbank vollständig gelöscht und neu erstellt werden musste. Bei Code First-Migrationen werden Testdaten nach Datenbankänderungen aufbewahrt, sodass in der Regel keine Testdaten in der Seed-Methode erforderlich sind. Tatsächlich möchten Sie nicht, dass die Seed
Methode Testdaten einfügt, wenn Sie Migrationen verwenden, um die Datenbank in der Produktion bereitzustellen, da die Methode in der Seed
Produktion ausgeführt wird. In diesem Fall soll die Seed
Methode in die Datenbank nur die Daten einfügen, die in die Produktion eingefügt werden sollen. Beispielsweise möchten Sie, dass die Datenbank tatsächliche Abteilungsnamen in die Department
Tabelle aufnehmen soll, wenn die Anwendung in der Produktion verfügbar wird.
In diesem Lernprogramm verwenden Sie Migrationen für die Bereitstellung, aber Ihre Seed
Methode fügt trotzdem Testdaten ein, um die Funktionsweise der Anwendungsfunktionalität einfacher zu erkennen, ohne viele Daten manuell einfügen zu müssen.
Ersetzen Sie den Inhalt der datei Configuration.cs durch den folgenden Code, der Testdaten in die neue Datenbank lädt.
namespace ContosoUniversity.Migrations { using System; using System.Collections.Generic; using System.Data.Entity.Migrations; using System.Linq; using ContosoUniversity.Models; internal sealed class Configuration : DbMigrationsConfiguration<ContosoUniversity.DAL.SchoolContext> { public Configuration() { AutomaticMigrationsEnabled = false; } protected override void Seed(ContosoUniversity.DAL.SchoolContext context) { var students = new List<Student> { new Student { FirstMidName = "Carson", LastName = "Alexander", EnrollmentDate = DateTime.Parse("2010-09-01") }, new Student { FirstMidName = "Meredith", LastName = "Alonso", EnrollmentDate = DateTime.Parse("2012-09-01") }, new Student { FirstMidName = "Arturo", LastName = "Anand", EnrollmentDate = DateTime.Parse("2013-09-01") }, new Student { FirstMidName = "Gytis", LastName = "Barzdukas", EnrollmentDate = DateTime.Parse("2012-09-01") }, new Student { FirstMidName = "Yan", LastName = "Li", EnrollmentDate = DateTime.Parse("2012-09-01") }, new Student { FirstMidName = "Peggy", LastName = "Justice", EnrollmentDate = DateTime.Parse("2011-09-01") }, new Student { FirstMidName = "Laura", LastName = "Norman", EnrollmentDate = DateTime.Parse("2013-09-01") }, new Student { FirstMidName = "Nino", LastName = "Olivetto", EnrollmentDate = DateTime.Parse("2005-08-11") } }; students.ForEach(s => context.Students.AddOrUpdate(p => p.LastName, s)); context.SaveChanges(); var courses = new List<Course> { new Course {CourseID = 1050, Title = "Chemistry", Credits = 3, }, new Course {CourseID = 4022, Title = "Microeconomics", Credits = 3, }, new Course {CourseID = 4041, Title = "Macroeconomics", Credits = 3, }, new Course {CourseID = 1045, Title = "Calculus", Credits = 4, }, new Course {CourseID = 3141, Title = "Trigonometry", Credits = 4, }, new Course {CourseID = 2021, Title = "Composition", Credits = 3, }, new Course {CourseID = 2042, Title = "Literature", Credits = 4, } }; courses.ForEach(s => context.Courses.AddOrUpdate(p => p.Title, s)); context.SaveChanges(); var enrollments = new List<Enrollment> { new Enrollment { StudentID = students.Single(s => s.LastName == "Alexander").StudentID, CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID, Grade = Grade.A }, new Enrollment { StudentID = students.Single(s => s.LastName == "Alexander").StudentID, CourseID = courses.Single(c => c.Title == "Microeconomics" ).CourseID, Grade = Grade.C }, new Enrollment { StudentID = students.Single(s => s.LastName == "Alexander").StudentID, CourseID = courses.Single(c => c.Title == "Macroeconomics" ).CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Alonso").StudentID, CourseID = courses.Single(c => c.Title == "Calculus" ).CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Alonso").StudentID, CourseID = courses.Single(c => c.Title == "Trigonometry" ).CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Alonso").StudentID, CourseID = courses.Single(c => c.Title == "Composition" ).CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Anand").StudentID, CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID }, new Enrollment { StudentID = students.Single(s => s.LastName == "Anand").StudentID, CourseID = courses.Single(c => c.Title == "Microeconomics").CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Barzdukas").StudentID, CourseID = courses.Single(c => c.Title == "Chemistry").CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Li").StudentID, CourseID = courses.Single(c => c.Title == "Composition").CourseID, Grade = Grade.B }, new Enrollment { StudentID = students.Single(s => s.LastName == "Justice").StudentID, CourseID = courses.Single(c => c.Title == "Literature").CourseID, Grade = Grade.B } }; foreach (Enrollment e in enrollments) { var enrollmentInDataBase = context.Enrollments.Where( s => s.Student.StudentID == e.StudentID && s.Course.CourseID == e.CourseID).SingleOrDefault(); if (enrollmentInDataBase == null) { context.Enrollments.Add(e); } } context.SaveChanges(); } } }
Die Seed-Methode verwendet das Datenbankkontextobjekt als Eingabeparameter, und der Code in der Methode verwendet dieses Objekt, um der Datenbank neue Entitäten hinzuzufügen. Für jeden Entitätstyp erstellt der Code eine Auflistung neuer Entitäten, fügt sie der entsprechenden DbSet-Eigenschaft hinzu und speichert dann die Änderungen in der Datenbank. Es ist nicht erforderlich, die SaveChanges-Methode nach jeder Gruppe von Entitäten aufzurufen, wie hier beschrieben. Dies hilft Ihnen jedoch, die Quelle eines Problems zu finden, wenn eine Ausnahme auftritt, während der Code in die Datenbank schreibt.
Einige der Anweisungen, die Daten einfügen, verwenden die AddOrUpdate-Methode , um einen "Upsert"-Vorgang auszuführen. Da die
Seed
Methode mit jeder Migration ausgeführt wird, können Sie nicht nur Daten einfügen, da die Zeilen, die Sie hinzufügen möchten, bereits nach der ersten Migration vorhanden sind, die die Datenbank erstellt. Der Vorgang "upsert" verhindert Fehler, die auftreten würden, wenn Sie versuchen, eine Zeile einzufügen, die bereits vorhanden ist, aber alle Änderungen an Daten außer Kraft setzt , die Sie möglicherweise beim Testen der Anwendung vorgenommen haben. Bei Testdaten in einigen Tabellen möchten Sie dies möglicherweise nicht: in einigen Fällen, wenn Sie Daten ändern, während Sie testen, dass Ihre Änderungen nach Datenbankaktualisierungen verbleiben sollen. In diesem Fall möchten Sie einen Vorgang zum bedingten Einfügen ausführen: Fügen Sie eine Zeile nur ein, wenn sie noch nicht vorhanden ist. Die Seed-Methode verwendet beide Ansätze.Der erste Parameter, der an die AddOrUpdate-Methode übergeben wird, gibt die Eigenschaft an, die verwendet werden soll, um zu überprüfen, ob bereits eine Zeile vorhanden ist. Für die von Ihnen bereitgestellten Testteilnehmerdaten kann die
LastName
Eigenschaft zu diesem Zweck verwendet werden, da jeder Nachname in der Liste eindeutig ist:context.Students.AddOrUpdate(p => p.LastName, s)
Dieser Code geht davon aus, dass Nachnamen eindeutig sind. Wenn Sie einen Kursteilnehmer manuell mit einem doppelten Nachnamen hinzufügen, erhalten Sie beim nächsten Ausführen einer Migration die folgende Ausnahme.
Sequenz enthält mehr als ein Element
Weitere Informationen zur Methode finden Sie im Blog von
AddOrUpdate
Julie Lerman unter EF 4.3 AddOrUpdate-Methode.Der Code, der
AddOrUpdate
Entitäten hinzufügtEnrollment
, verwendet die Methode nicht. Es überprüft, ob eine Entität bereits vorhanden ist und fügt die Entität ein, wenn sie nicht vorhanden ist. Dieser Ansatz behält Änderungen bei, die Sie an einer Registrierungsnote vornehmen, wenn Migrationen ausgeführt werden. Der Code durchläuft jedes Mitglied derEnrollment
Liste , und wenn die Registrierung in der Datenbank nicht gefunden wird, wird die Registrierung der Datenbank hinzugefügt. Wenn Sie die Datenbank zum ersten Mal aktualisieren, ist die Datenbank leer, sodass jede Registrierung hinzugefügt wird.foreach (Enrollment e in enrollments) { var enrollmentInDataBase = context.Enrollments.Where( s => s.Student.StudentID == e.Student.StudentID && s.Course.CourseID == e.Course.CourseID).SingleOrDefault(); if (enrollmentInDataBase == null) { context.Enrollments.Add(e); } }
Informationen zum Debuggen der
Seed
Methode und zum Behandeln redundanter Daten wie zwei Studenten namens "Alexander Carson" finden Sie im Blog von Rick Anderson unter Seeding and Debugging Entity Framework (EF) DBs .Erstellen Sie das Projekt.
Erstellen und Ausführen der ersten Migration
Geben Sie im Fenster Paket-Manager Konsole die folgenden Befehle ein:
add-migration InitialCreate update-database
Der
add-migration
Befehl fügt dem Ordner "Migrationen" eine [DateStamp]-_InitialCreate.cs Datei hinzu , die Code enthält, der die Datenbank erstellt. Der erste Parameter (InitialCreate)
wird für den Dateinamen verwendet und kann beliebig sein. In der Regel wählen Sie ein Wort oder einen Ausdruck aus, der zusammenfasst, was in der Migration geschieht. Sie können einer späteren Migration beispielsweise den Namen „AddDepartmentTable“ geben.Die
Up
Methode derInitialCreate
Klasse erstellt die Datenbanktabellen, die den Datenmodellentitätssätzen entsprechen, und dieDown
Methode löscht sie. Die Migrationsfunktion ruft die MethodeUp
auf, um die Datenmodelländerungen für eine Migration zu implementieren. Wenn Sie einen Befehl eingeben, um ein Rollback für das Update auszuführen, ruft die Migrationsfunktion die MethodeDown
auf. Der folgende Code zeigt den Inhalt derInitialCreate
Datei:namespace ContosoUniversity.Migrations { using System; using System.Data.Entity.Migrations; public partial class InitialCreate : DbMigration { public override void Up() { CreateTable( "dbo.Student", c => new { StudentID = c.Int(nullable: false, identity: true), LastName = c.String(), FirstMidName = c.String(), EnrollmentDate = c.DateTime(nullable: false), }) .PrimaryKey(t => t.StudentID); CreateTable( "dbo.Enrollment", c => new { EnrollmentID = c.Int(nullable: false, identity: true), CourseID = c.Int(nullable: false), StudentID = c.Int(nullable: false), Grade = c.Int(), }) .PrimaryKey(t => t.EnrollmentID) .ForeignKey("dbo.Course", t => t.CourseID, cascadeDelete: true) .ForeignKey("dbo.Student", t => t.StudentID, cascadeDelete: true) .Index(t => t.CourseID) .Index(t => t.StudentID); CreateTable( "dbo.Course", c => new { CourseID = c.Int(nullable: false), Title = c.String(), Credits = c.Int(nullable: false), }) .PrimaryKey(t => t.CourseID); } public override void Down() { DropIndex("dbo.Enrollment", new[] { "StudentID" }); DropIndex("dbo.Enrollment", new[] { "CourseID" }); DropForeignKey("dbo.Enrollment", "StudentID", "dbo.Student"); DropForeignKey("dbo.Enrollment", "CourseID", "dbo.Course"); DropTable("dbo.Course"); DropTable("dbo.Enrollment"); DropTable("dbo.Student"); } } }
Der
update-database
Befehl führt dieUp
Methode aus, um die Datenbank zu erstellen, und anschließend wird dieSeed
Methode zum Auffüllen der Datenbank ausgeführt.
Für Ihr Datenmodell wurde nun eine SQL Server-Datenbank erstellt. Der Name der Datenbank lautet "ContosoUniversity", und die .mdf Datei befindet sich im App_Data Ordner Ihres Projekts, da sie in Ihrem Verbindungszeichenfolge angegeben wurde.
Sie können entweder Server-Explorer oder SQL Server-Objekt-Explorer (SSOX) verwenden, um die Datenbank in Visual Studio anzuzeigen. In diesem Lernprogramm verwenden Sie den Server-Explorer. In Visual Studio Express 2012 für Web wird Der Server-Explorer als Datenbank-Explorer bezeichnet.
Klicken Sie im Menü "Ansicht" auf "Server-Explorer".
Klicken Sie auf das Symbol "Verbindung hinzufügen" .
Wenn Sie mit dem Dialogfeld "Datenquelle auswählen" aufgefordert werden, klicken Sie auf Microsoft SQL Server, und klicken Sie dann auf "Weiter".
Geben Sie im Dialogfeld "Verbindung hinzufügen" (localdb)\v11.0 für den Servernamen ein. Wählen Sie unter "Datenbankname auswählen" oder " ContosoUniversity" aus.
Klicken Sie auf OK.
Erweitern Sie SchoolContext , und erweitern Sie dann Tabellen.
Klicken Sie mit der rechten Maustaste auf die Tabelle "Student ", und klicken Sie auf " Tabellendaten anzeigen", um die erstellten Spalten und die Zeilen anzuzeigen, die in die Tabelle eingefügt wurden.
Erstellen eines Schülercontrollers und ansichten
Der nächste Schritt besteht darin, einen ASP.NET MVC-Controller und -Ansichten in Ihrer Anwendung zu erstellen, der mit einer dieser Tabellen arbeiten kann.
Um einen
Student
Controller zu erstellen, klicken Sie mit der rechten Maustaste auf den Ordner "Controller" in Projektmappen-Explorer, wählen Sie "Hinzufügen" aus, und klicken Sie dann auf "Controller". Nehmen Sie im Dialogfeld "Controller hinzufügen" die folgenden Auswahlmöglichkeiten vor, und klicken Sie dann auf "Hinzufügen":Controllername: StudentController.
Vorlage: MVC-Controller mit Lese-/Schreibaktionen und -ansichten mit Entity Framework.
Modellklasse: Student (ContosoUniversity.Models). (Wenn diese Option in der Dropdownliste nicht angezeigt wird, erstellen Sie das Projekt, und versuchen Sie es erneut.)
Datenkontextklasse: SchoolContext (ContosoUniversity.Models).
Ansichten: Razor (CSHTML). (Der Standardwert.)
Visual Studio öffnet die Datei "Controller\StudentController.cs ". Es wird eine Klassenvariable erstellt, die ein Datenbankkontextobjekt instanziiert:
private SchoolContext db = new SchoolContext();
Die
Index
Aktionsmethode ruft eine Liste der Kursteilnehmer aus der Entität "Studenten " ab, indem sie dieStudents
Eigenschaft der Datenbankkontextinstanz lesen:public ViewResult Index() { return View(db.Students.ToList()); }
In der Ansicht "Student\Index.cshtml " wird diese Liste in einer Tabelle angezeigt:
<table> <tr> <th> @Html.DisplayNameFor(model => model.LastName) </th> <th> @Html.DisplayNameFor(model => model.FirstMidName) </th> <th> @Html.DisplayNameFor(model => model.EnrollmentDate) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.LastName) </td> <td> @Html.DisplayFor(modelItem => item.FirstMidName) </td> <td> @Html.DisplayFor(modelItem => item.EnrollmentDate) </td> <td> @Html.ActionLink("Edit", "Edit", new { id=item.StudentID }) | @Html.ActionLink("Details", "Details", new { id=item.StudentID }) | @Html.ActionLink("Delete", "Delete", new { id=item.StudentID }) </td> </tr> }
Drücken Sie STRG+F5, um das Projekt auszuführen.
Klicken Sie auf die Registerkarte "Kursteilnehmer ", um die von der
Seed
Methode eingefügten Testdaten anzuzeigen.
Konventionen
Die Menge des Codes, den Sie schreiben mussten, damit Das Entity Framework eine vollständige Datenbank für Sie erstellen kann, ist aufgrund der Verwendung von Konventionen oder Annahmen, die das Entity Framework vorgibt, minimal. Einige davon wurden bereits erwähnt:
- Die pluralisierten Formen von Entitätsklassennamen werden als Tabellennamen verwendet.
- Eigenschaftennamen von Entitäten werden als Spaltennamen verwendet.
- Entitätseigenschaften, die benannt
ID
oder klassennameID
sind, werden als Primärschlüsseleigenschaften erkannt.
Sie haben gesehen, dass Konventionen überschrieben werden können (z. B. haben Sie angegeben, dass Tabellennamen nicht pluralisiert werden sollen), und Sie erfahren mehr über Konventionen und wie Sie sie im Lernprogramm zum Erstellen eines komplexeren Datenmodells weiter unten in dieser Reihe überschreiben. Weitere Informationen finden Sie unter Code First Conventions.
Zusammenfassung
Sie haben nun eine einfache Anwendung erstellt, die das Entity Framework und SQL Server Express zum Speichern und Anzeigen von Daten verwendet. Im folgenden Lernprogramm erfahren Sie, wie Sie grundlegende CRUD-Vorgänge (Erstellen, Lesen, Aktualisieren, Löschen) ausführen. Sie können Feedback unten auf dieser Seite hinterlassen. Bitte teilen Sie uns mit, wie Ihnen dieser Teil des Lernprogramms gefallen hat und wie wir es verbessern können.
Links zu anderen Entity Framework-Ressourcen finden Sie in der ASP.NET Datenzugriffs-Inhaltszuordnung.