Freigeben über


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.

Students_Index_page

Screenshots, die die Suchseite

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).

New_project_dialog_box

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.

Project_template_options

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>&copy; @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.

Contoso_University_home_page

Erstellen des Datenmodells

Als nächstes erstellen Sie Entitätsklassen für die Contoso University-Anwendung. Sie beginnen mit den folgenden drei Entitäten:

Class_diagram

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

Student_entity

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

Enrollment_entity

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“

Course_entity

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, Coursesund Enrollments. Stattdessen sind Studentdie Tabellennamen , Courseund 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

  1. Klicken Sie im Menü Extras auf NuGet-Paket-Manager und dann auf Paket-Manager-Konsole.

    Selecting_Package_Manager_Console

  2. Geben Sie an der PM> Eingabeaufforderung den folgenden Befehl ein:

    enable-migrations -contexttypename SchoolContext
    

    Befehl

    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.

    Migrationsordner

    Die Configuration Klasse enthält eine Seed 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.

  1. 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 der EnrollmentListe , 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 .

  2. Erstellen Sie das Projekt.

Erstellen und Ausführen der ersten Migration

  1. Geben Sie im Fenster Paket-Manager Konsole die folgenden Befehle ein:

    add-migration InitialCreate
    update-database
    

    Screenshot des Paket-Manager Konsolenfensters. Die Befehle fügen den Bindestrich für die Migration mit dem Unterstrich

    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.

    Migrationsordner mit anfänglicher Migration

    Die Up Methode der InitialCreate Klasse erstellt die Datenbanktabellen, die den Datenmodellentitätssätzen entsprechen, und die Down Methode löscht sie. Die Migrationsfunktion ruft die Methode Up 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 Methode Down auf. Der folgende Code zeigt den Inhalt der InitialCreate 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 die Up Methode aus, um die Datenbank zu erstellen, und anschließend wird die Seed 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.

  1. Klicken Sie im Menü "Ansicht" auf "Server-Explorer".

  2. Klicken Sie auf das Symbol "Verbindung hinzufügen" .

    Screenshot des Fensters

  3. Wenn Sie mit dem Dialogfeld "Datenquelle auswählen" aufgefordert werden, klicken Sie auf Microsoft SQL Server, und klicken Sie dann auf "Weiter".

    Screenshot des Dialogfelds

  4. 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.

    Screenshot des Dialogfelds

  5. Klicken Sie auf OK.

  6. Erweitern Sie SchoolContext , und erweitern Sie dann Tabellen.

    Screenshot der Seite

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

    Tabelle

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.

  1. 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.)

      Add_Controller_dialog_box_for_Student_controller

  2. 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 die Students 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>
    }
    
  3. 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.

    Seite

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 klassenname ID 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.