Freigeben über


Tutorial: Informationen zu erweiterten EF-Szenarien für eine MVC 5-Web-App

Im vorherigen Tutorial haben Sie die Vererbung von Tabellen pro Hierarchie implementiert. Dieses Tutorial enthält eine Einführung in mehrere Themen, die hilfreich sind, wenn Sie über die Grundlagen der Entwicklung von ASP.NET Webanwendungen hinausgehen, die Entity Framework Code First verwenden. Die ersten Abschnitte enthalten schrittweise Anweisungen, die Sie durch den Code und die Verwendung von Visual Studio zum Ausführen von Aufgaben führen. Die folgenden Abschnitte enthalten mehrere Themen mit kurzen Einführungen, gefolgt von Links zu Ressourcen für weitere Informationen.

Für die meisten dieser Themen arbeiten Sie mit Seiten, die Sie bereits erstellt haben. Um SQL-Rohdaten für Massenupdates zu verwenden, erstellen Sie eine neue Seite, auf der die Anzahl der Guthaben aller Kurse in der Datenbank aktualisiert wird:

Update_Course_Credits_initial_page

In diesem Tutorial:

  • Durchführen unformatierter SQL-Abfragen
  • Ausführen von Abfragen ohne Nachverfolgung
  • An die Datenbank gesendete SQL-Abfragen untersuchen

Außerdem erfahren Sie mehr über Folgendes:

  • Erstellen einer Abstraktionsebene
  • Proxyklassen
  • Automatische Änderungserkennung
  • Automatische Validierung
  • Entity Framework Power Tools
  • Entity Framework-Quellcode

Voraussetzungen

Durchführen unformatierter SQL-Abfragen

Die Entity Framework Code First-API enthält Methoden, mit denen Sie SQL-Befehle direkt an die Datenbank übergeben können. Sie haben folgende Optionen:

  • Verwenden Sie die DbSet.SqlQuery-Methode für Abfragen, die Entitätstypen zurückgeben. Die zurückgegebenen Objekte müssen vom Typ sein, der DbSet vom Objekt erwartet wird, und sie werden automatisch vom Datenbankkontext nachverfolgt, es sei denn, Sie deaktivieren die Nachverfolgung. (Weitere Informationen zur AsNoTracking-Methode finden Sie im folgenden Abschnitt.)
  • Verwenden Sie die Database.SqlQuery-Methode für Abfragen, die Typen zurückgeben, die keine Entitäten sind. Die zurückgegebenen Daten werden nicht vom Datenbankkontext nachverfolgt, auch wenn Sie diese Methode zum Abrufen von Entitätstypen verwenden.
  • Verwenden Sie den Database.ExecuteSqlCommand für Nicht-Abfragebefehle.

Einer der Vorteile von Entity Framework ist die Tatsache, dass vermieden wird, den Code zu eng an eine bestimmte Methode zum Speichern von Daten zu binden. Dies geschieht, indem SQL-Abfragen und -Befehle für Sie generiert werden. Somit müssen Sie sie nicht selbst schreiben. Es gibt jedoch außergewöhnliche Szenarien, in denen Sie bestimmte SQL-Abfragen ausführen müssen, die Sie manuell erstellt haben, und diese Methoden ermöglichen es Ihnen, solche Ausnahmen zu behandeln.

Dies trifft immer zu, wenn Sie SQL-Befehle in einer Webanwendung ausführen. Treffen Sie deshalb Vorsichtsmaßnahmen, um Ihre Website vor Angriffen durch Einschleusung von SQL-Befehlen zu schützen. Verwenden Sie dazu parametrisierte Abfragen, um sicherzustellen, dass Zeichenfolgen, die von einer Webseite übermittelt werden, nicht als SQL-Befehle interpretiert werden können. In diesem Tutorial verwenden Sie parametrisierte Abfragen beim Integrieren von Benutzereingaben in eine Abfrage.

Aufrufen einer Abfrage, die Entitäten zurückgibt

Die DbSet<TEntity-Klasse> stellt eine Methode bereit, mit der Sie eine Abfrage ausführen können, die eine Entität vom Typ TEntityzurückgibt. Um zu sehen, wie dies funktioniert, ändern Sie den Code in der Details -Methode des Department Controllers.

Ersetzen Sie in DepartmentController.cs in der Details -Methode den db.Departments.FindAsync Methodenaufruf durch einen db.Departments.SqlQuery Methodenaufruf, wie im folgenden hervorgehobenen Code gezeigt:

public async Task<ActionResult> Details(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }

    // Commenting out original code to show how to use a raw SQL query.
    //Department department = await db.Departments.FindAsync(id);

    // Create and execute raw SQL query.
    string query = "SELECT * FROM Department WHERE DepartmentID = @p0";
    Department department = await db.Departments.SqlQuery(query, id).SingleOrDefaultAsync();
    
    if (department == null)
    {
        return HttpNotFound();
    }
    return View(department);
}

Wählen Sie die Registerkarte Departments (Abteilungen) und dann Details für eine der Abteilungen aus. So können Sie überprüfen, ob der neue Code korrekt funktioniert. Stellen Sie sicher, dass alle Daten wie erwartet angezeigt werden.

Aufrufen einer Abfrage, die andere Objekttypen zurückgibt

Sie haben zuvor ein Statistikraster für Studenten für die Infoseite erstellt, das die Anzahl der Studenten für jedes Anmeldedatum zeigt. Der Code, der dies in "HomeController.cs " ausführt, verwendet LINQ:

var data = from student in db.Students
           group student by student.EnrollmentDate into dateGroup
           select new EnrollmentDateGroup()
           {
               EnrollmentDate = dateGroup.Key,
               StudentCount = dateGroup.Count()
           };

Angenommen, Sie möchten den Code schreiben, der diese Daten direkt in SQL abruft, anstatt LINQ zu verwenden. Dazu müssen Sie eine Abfrage ausführen, die etwas anderes als Entitätsobjekte zurückgibt. Dies bedeutet, dass Sie die Database.SqlQuery-Methode verwenden müssen.

Ersetzen Sie in HomeController.cs die LINQ-Anweisung in der About -Methode durch eine SQL-Anweisung, wie im folgenden hervorgehobenen Code gezeigt:

public ActionResult About()
{
    // Commenting out LINQ to show how to do the same thing in SQL.
    //IQueryable<EnrollmentDateGroup> = from student in db.Students
    //           group student by student.EnrollmentDate into dateGroup
    //           select new EnrollmentDateGroup()
    //           {
    //               EnrollmentDate = dateGroup.Key,
    //               StudentCount = dateGroup.Count()
    //           };

    // SQL version of the above LINQ code.
    string query = "SELECT EnrollmentDate, COUNT(*) AS StudentCount "
        + "FROM Person "
        + "WHERE Discriminator = 'Student' "
        + "GROUP BY EnrollmentDate";
    IEnumerable<EnrollmentDateGroup> data = db.Database.SqlQuery<EnrollmentDateGroup>(query);

    return View(data.ToList());
}

Führen Sie die Seite Info aus. Stellen Sie sicher, dass die gleichen Daten wie zuvor angezeigt werden.

Aufrufen einer Updateabfrage

Angenommen, Administratoren der Contoso University möchten massenweise Änderungen in der Datenbank durchführen können, z. B. die Anzahl der Credits für jeden Kurs ändern. Wenn die Universität über eine große Anzahl an Kursen verfügt, wäre es ineffizient, sie alle als Entitäten abzurufen und separat zu ändern. In diesem Abschnitt implementieren Sie eine Webseite, mit der der Benutzer einen Faktor angeben kann, um den die Anzahl der Guthaben für alle Kurse ändern kann, und Sie nehmen die Änderung durch Ausführen einer SQL-Anweisung UPDATE vor.

Fügen Sie in CourseController.cs Methoden für HttpGet und HttpPosthinzuUpdateCourseCredits:

public ActionResult UpdateCourseCredits()
{
    return View();
}

[HttpPost]
public ActionResult UpdateCourseCredits(int? multiplier)
{
    if (multiplier != null)
    {
        ViewBag.RowsAffected = db.Database.ExecuteSqlCommand("UPDATE Course SET Credits = Credits * {0}", multiplier);
    }
    return View();
}

Wenn der Controller eine HttpGet Anforderung verarbeitet, wird in der ViewBag.RowsAffected Variablen nichts zurückgegeben, und in der Ansicht werden ein leeres Textfeld und eine Schaltfläche zum Senden angezeigt.

Wenn auf die Schaltfläche Aktualisieren geklickt wird, wird die HttpPost -Methode aufgerufen, und multiplier der Wert wird in das Textfeld eingegeben. Der Code führt dann die SQL aus, die Kurse aktualisiert, und gibt die Anzahl der betroffenen Zeilen an die Ansicht in der ViewBag.RowsAffected Variablen zurück. Wenn die Ansicht einen Wert in dieser Variablen erhält, wird die Anzahl der aktualisierten Zeilen anstelle des Textfelds und der Schaltfläche "Senden" angezeigt.

Klicken Sie in CourseController.cs mit der rechten Maustaste auf eine der UpdateCourseCredits Methoden, und klicken Sie dann auf Ansicht hinzufügen. Das Dialogfeld Ansicht hinzufügen wird angezeigt. Übernehmen Sie die Standardwerte, und wählen Sie Hinzufügen aus.

Ersetzen Sie in Views\Course\UpdateCourseCredits.cshtml den Vorlagencode durch den folgenden Code:

@model ContosoUniversity.Models.Course

@{
    ViewBag.Title = "UpdateCourseCredits";
}

<h2>Update Course Credits</h2>

@if (ViewBag.RowsAffected == null)
{
    using (Html.BeginForm())
    {
        <p>
            Enter a number to multiply every course's credits by: @Html.TextBox("multiplier")
        </p>
        <p>
            <input type="submit" value="Update" />
        </p>
    }
}
@if (ViewBag.RowsAffected != null)
{
    <p>
        Number of rows updated: @ViewBag.RowsAffected
    </p>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

Führen Sie die UpdateCourseCredits-Methode aus, indem Sie die Registerkarte Courses (Kurse) auswählen, und dann „/UpdateCourseCredits“ am Ende der URL in die Adressleiste des Browsers einfügen (z.B.: http://localhost:50205/Course/UpdateCourseCredits). Geben Sie eine Zahl in das Textfeld ein:

Update_Course_Credits_initial_page_with_2_entered

Klicke auf Aktualisieren. Die Anzahl der betroffenen Zeilen wird angezeigt.

Klicken Sie auf Zurück zur Liste, um die Kursliste mit der geänderte Anzahl von Credits anzuzeigen.

Weitere Informationen zu unformatierten SQL-Abfragen finden Sie unter Raw SQL-Abfragen auf MSDN.

Abfragen ohne Nachverfolgung

Wenn ein Datenbankkontext Tabellenzeilen abruft und Entitätsobjekte erstellt, die diese darstellen, verfolgen sie standardgemäß, ob die Entitäten im Arbeitsspeicher mit dem Inhalt der Datenbank synchronisiert sind. Die Daten im Arbeitsspeicher fungieren als Cache und werden verwendet, wenn Sie eine Entität aktualisieren. Diese Zwischenspeicherung ist in Webanwendungen oft überflüssig, da Kontextinstanzen in der Regel kurzlebig sind (eine neue wird bei jeder Anforderung erstellt und gelöscht), und der Kontext, der eine Entität liest, wird in der Regel gelöscht, bevor diese Entität erneut verwendet wird.

Sie können die Nachverfolgung von Entitätsobjekten im Arbeitsspeicher mithilfe der AsNoTracking-Methode deaktivieren. Typische Szenarios, in denen Sie das möglicherweise tun wollen, umfassen Folgendes:

  • Eine Abfrage ruft eine so große Datenmenge ab, dass das Deaktivieren der Nachverfolgung die Leistung spürbar verbessern kann.
  • Sie möchten eine Entität anfügen, um sie zu aktualisieren, aber Sie haben zuvor dieselbe Entität für einen anderen Zweck abgerufen. Da diese Entität bereits vom Datenbankkontext nachverfolgt wird, können Sie die zu ändernde Entität nicht anfügen. Eine Möglichkeit, diese Situation zu behandeln, besteht darin, die AsNoTracking Option mit der vorherigen Abfrage zu verwenden.

Ein Beispiel, das die Verwendung der AsNoTracking-Methode veranschaulicht, finden Sie in der früheren Version dieses Tutorials. In dieser Version des Tutorials wird das Flag Modified für eine vom Modellbinder erstellte Entität in der Edit-Methode nicht festgelegt, sodass sie nicht benötigt AsNoTracking.

Untersuchen von SQL-Nachrichten, die an die Datenbank gesendet werden

Manchmal ist es hilfreich, die tatsächlichen SQL-Abfragen anzuzeigen, die an die Datenbank gesendet werden. In einem früheren Tutorial haben Sie erfahren, wie Sie dies in Interceptorcode tun. Nun werden einige Möglichkeiten angezeigt, dies ohne Das Schreiben von Interceptorcode zu tun. Um dies auszuprobieren, sehen Sie sich eine einfache Abfrage an und sehen sich dann an, was damit geschieht, während Sie Optionen wie eifrig laden, filtern und sortieren hinzufügen.

Ersetzen Sie in Controllers/CourseController die Index -Methode durch den folgenden Code, um das laden vorübergehend zu beenden:

public ActionResult Index()
{
    var courses = db.Courses;
    var sql = courses.ToString();
    return View(courses.ToList());
}

Legen Sie nun einen Haltepunkt für die return -Anweisung fest (F9 mit dem Cursor in dieser Zeile). Drücken Sie F5 , um das Projekt im Debugmodus auszuführen, und wählen Sie die Seite Kursindex aus. Wenn der Code den Haltepunkt erreicht, untersuchen Sie die sql Variable. Sie sehen die Abfrage, die an SQL Server gesendet wird. Es handelt sich um eine einfache Select Anweisung.

{SELECT 
[Extent1].[CourseID] AS [CourseID], 
[Extent1].[Title] AS [Title], 
[Extent1].[Credits] AS [Credits], 
[Extent1].[DepartmentID] AS [DepartmentID]
FROM [Course] AS [Extent1]}

Klicken Sie auf die Lupe, um die Abfrage in der Textschnellansicht anzuzeigen.

Ein Screenshot, der den Kurscontroller mit hervorgehobener Codezeile zeigt. Ein weiterer Screenshot, der zeigt, dass die Textschnellansicht geöffnet ist und eine Lupe im Feld Wert rot eingekreist ist.

Nun fügen Sie der Seite Kursindex eine Dropdownliste hinzu, damit Benutzer nach einer bestimmten Abteilung filtern können. Sie sortieren die Kurse nach Titel, und Sie geben eager loading für die Department Navigationseigenschaft an.

Ersetzen Sie in CourseController.cs die Index -Methode durch den folgenden Code:

public ActionResult Index(int? SelectedDepartment)
{
    var departments = db.Departments.OrderBy(q => q.Name).ToList();
    ViewBag.SelectedDepartment = new SelectList(departments, "DepartmentID", "Name", SelectedDepartment);
    int departmentID = SelectedDepartment.GetValueOrDefault();

    IQueryable<Course> courses = db.Courses
        .Where(c => !SelectedDepartment.HasValue || c.DepartmentID == departmentID)
        .OrderBy(d => d.CourseID)
        .Include(d => d.Department);
    var sql = courses.ToString();
    return View(courses.ToList());
}

Stellen Sie den Haltepunkt für die return Anweisung wieder her.

Die -Methode empfängt den ausgewählten Wert der Dropdownliste im SelectedDepartment Parameter. Wenn nichts ausgewählt ist, ist dieser Parameter NULL.

Eine SelectList Auflistung, die alle Abteilungen enthält, wird an die Ansicht für die Dropdownliste übergeben. Die an den SelectList Konstruktor übergebenen Parameter geben den Wertfeldnamen, den Textfeldnamen und das ausgewählte Element an.

Für die Get Methode des Course Repositorys gibt der Code einen Filterausdruck, eine Sortierreihenfolge und eifriges Laden für die Department Navigationseigenschaft an. Der Filterausdruck wird immer zurückgegeben true , wenn in der Dropdownliste nichts ausgewählt ist (d. a SelectedDepartment . null).

Fügen Sie in Views\Course\Index.cshtml unmittelbar vor dem öffnenden table Tag den folgenden Code hinzu, um die Dropdownliste und eine Schaltfläche zum Senden zu erstellen:

@using (Html.BeginForm())
{
    <p>Select Department: @Html.DropDownList("SelectedDepartment","All")   
    <input type="submit" value="Filter" /></p>
}

Wenn der Haltepunkt noch festgelegt ist, führen Sie die Seite Kursindex aus. Fahren Sie mit dem ersten Mal fort, wenn der Code einen Haltepunkt erreicht, sodass die Seite im Browser angezeigt wird. Wählen Sie in der Dropdownliste eine Abteilung aus, und klicken Sie auf Filtern.

Diesmal ist der erste Haltepunkt für die Abteilungsabfrage für die Dropdownliste. Überspringen Sie dies, und zeigen Sie die query Variable an, wenn der Code das nächste Mal den Haltepunkt erreicht, um zu sehen, wie die Course Abfrage jetzt aussieht. Es wird etwa folgendes angezeigt:

SELECT 
    [Project1].[CourseID] AS [CourseID], 
    [Project1].[Title] AS [Title], 
    [Project1].[Credits] AS [Credits], 
    [Project1].[DepartmentID] AS [DepartmentID], 
    [Project1].[DepartmentID1] AS [DepartmentID1], 
    [Project1].[Name] AS [Name], 
    [Project1].[Budget] AS [Budget], 
    [Project1].[StartDate] AS [StartDate], 
    [Project1].[InstructorID] AS [InstructorID], 
    [Project1].[RowVersion] AS [RowVersion]
    FROM ( SELECT 
        [Extent1].[CourseID] AS [CourseID], 
        [Extent1].[Title] AS [Title], 
        [Extent1].[Credits] AS [Credits], 
        [Extent1].[DepartmentID] AS [DepartmentID], 
        [Extent2].[DepartmentID] AS [DepartmentID1], 
        [Extent2].[Name] AS [Name], 
        [Extent2].[Budget] AS [Budget], 
        [Extent2].[StartDate] AS [StartDate], 
        [Extent2].[InstructorID] AS [InstructorID], 
        [Extent2].[RowVersion] AS [RowVersion]
        FROM  [dbo].[Course] AS [Extent1]
        INNER JOIN [dbo].[Department] AS [Extent2] ON [Extent1].[DepartmentID] = [Extent2].[DepartmentID]
        WHERE @p__linq__0 IS NULL OR [Extent1].[DepartmentID] = @p__linq__1
    )  AS [Project1]
    ORDER BY [Project1].[CourseID] ASC

Sie können sehen, dass die Abfrage jetzt eine JOIN Abfrage ist, die Daten zusammen mit den Course Daten lädtDepartment, und dass sie eine WHERE -Klausel enthält.

Entfernen Sie die var sql = courses.ToString() Zeile.

Erstellen einer Abstraktionsschicht

Viele Entwickler schreiben Code, um das Repository- und Arbeitseinheitsmuster als Wrapper um den Code zu implementieren, der mit dem Entity Framework arbeitet. Diese Muster sollen eine Abstraktionsebene zwischen der Datenzugriffsebene und den Geschäftslogikebene einer Anwendung erstellen. Die Implementierung dieser Muster unterstützt die Isolation Ihrer Anwendung vor Änderungen im Datenspeicher und kann automatisierte Komponententests oder eine testgesteuerte Entwicklung (Test-Driven Development, TDD) erleichtern. Das Schreiben von zusätzlichem Code zum Implementieren dieser Muster ist jedoch nicht immer die beste Wahl für Anwendungen, die EF verwenden, aus mehreren Gründen:

  • Die EF-Kontextklasse isoliert Ihren Code selbst vor datenspeicherspezifischem Code.
  • Die EF-Kontextklasse kann als Arbeitseinheitsklasse für Updates der Datenbank fungieren, die Sie mithilfe von EF ausführen.
  • Die in Entity Framework 6 eingeführten Features erleichtern die Implementierung von TDD ohne Schreiben von Repositorycode.

Weitere Informationen zum Implementieren des Repositorys und der Arbeitseinheitsmuster finden Sie in der Entity Framework 5-Version dieser Tutorialreihe. Informationen zu Möglichkeiten zum Implementieren von TDD in Entity Framework 6 finden Sie in den folgenden Ressourcen:

Proxyklassen

Wenn Entity Framework Entitätsinstanzen erstellt (z. B. wenn Sie eine Abfrage ausführen), werden diese häufig als Instanzen eines dynamisch generierten abgeleiteten Typs erstellt, der als Proxy für die Entität fungiert. Sehen Sie sich beispielsweise die folgenden beiden Debuggerimages an. In der ersten Abbildung sehen Sie, dass die student Variable der erwartete Student Typ ist, unmittelbar nachdem Sie die Entität instanziiert haben. In der zweiten Abbildung wird die Proxyklasse angezeigt, nachdem EF zum Lesen einer Studentenentität aus der Datenbank verwendet wurde.

Vor der Proxyklasse

Nach der Proxyklasse

Diese Proxyklasse überschreibt einige virtuelle Eigenschaften der Entität, um Hooks zum automatischen Ausführen von Aktionen einzufügen, wenn auf die Eigenschaft zugegriffen wird. Eine Funktion, für die dieser Mechanismus verwendet wird, ist das verzögerte Laden.

Die meiste Zeit müssen Sie sich nicht über diese Verwendung von Proxys bewusst sein, aber es gibt Ausnahmen:

  • In einigen Szenarien möchten Sie möglicherweise verhindern, dass Entity Framework Proxyinstanzen erstellt. Wenn Sie beispielsweise Entitäten serialisieren, möchten Sie in der Regel die POCO-Klassen, nicht die Proxyklassen. Eine Möglichkeit, Serialisierungsprobleme zu vermeiden, besteht darin, Datenübertragungsobjekte (DTOs) anstelle von Entitätsobjekten zu serialisieren, wie im Tutorial Verwenden der Web-API mit Entity Framework gezeigt. Eine andere Möglichkeit besteht darin, die Proxyerstellung zu deaktivieren.
  • Wenn Sie eine Entitätsklasse mit dem new Operator instanziieren, erhalten Sie keinen Proxy instance. Dies bedeutet, dass Sie keine Funktionen wie verzögertes Laden und automatische Änderungsnachverfolgung erhalten. Dies ist in der Regel in Ordnung. Sie benötigen im Allgemeinen kein verzögertes Laden, da Sie eine neue Entität erstellen, die sich nicht in der Datenbank befindet, und Sie benötigen in der Regel keine Änderungsnachverfolgung, wenn Sie die Entität explizit als Addedmarkieren. Wenn Sie jedoch ein verzögertes Laden benötigen und Sie eine Änderungsnachverfolgung benötigen, können Sie mithilfe der Create-Methode der DbSet -Klasse neue Entitätsinstanzen mit Proxys erstellen.
  • Möglicherweise möchten Sie einen tatsächlichen Entitätstyp aus einem Proxytyp abrufen. Sie können die GetObjectType-Methode der ObjectContext -Klasse verwenden, um den tatsächlichen Entitätstyp eines Proxytyps instance abzurufen.

Weitere Informationen finden Sie unter Arbeiten mit Proxys auf MSDN.

Automatische Änderungserkennung

Entity Framework bestimmt wie eine Entität geändert wurde (und welche Updates an die Datenbank gesendet werden müssen), indem die aktuellen Werte einer Entität mit den ursprünglichen Werten verglichen werden. Die ursprünglichen Werte werden gespeichert, wenn die Entität abgefragt oder angefügt wird. Einige der Methoden, die automatisch eine Änderungserkennung durchführen, sind die folgenden:

  • DbSet.Find
  • DbSet.Local
  • DbSet.Remove
  • DbSet.Add
  • DbSet.Attach
  • DbContext.SaveChanges
  • DbContext.GetValidationErrors
  • DbContext.Entry
  • DbChangeTracker.Entries

Wenn Sie eine große Anzahl von Entitäten nachverfolgen und eine dieser Methoden mehrmals in einer Schleife aufrufen, können Sie erhebliche Leistungsverbesserungen erzielen, indem Sie die automatische Änderungserkennung mithilfe der AutoDetectChangesEnabled-Eigenschaft vorübergehend deaktivieren. Weitere Informationen finden Sie unter Automatisches Erkennen von Änderungen auf MSDN.

Automatische Validierung

Wenn Sie die SaveChanges Methode aufrufen, überprüft Entity Framework standardmäßig die Daten in allen Eigenschaften aller geänderten Entitäten, bevor die Datenbank aktualisiert wird. Wenn Sie eine große Anzahl von Entitäten aktualisiert haben und die Daten bereits überprüft haben, ist diese Arbeit unnötig, und Sie könnten den Prozess zum Speichern der Änderungen weniger Zeit in Anspruch nehmen, indem Sie die Überprüfung vorübergehend deaktivieren. Dazu können Sie die ValidateOnSaveEnabled-Eigenschaft verwenden. Weitere Informationen finden Sie unter Validierung auf MSDN.

Entity Framework Power Tools

Entity Framework Power Tools ist ein Visual Studio-Add-In, das zum Erstellen der In diesen Tutorials gezeigten Datenmodelldiagramme verwendet wurde. Die Tools können auch andere Funktionen ausführen, z. B. Entitätsklassen basierend auf den Tabellen in einer vorhandenen Datenbank generieren, sodass Sie die Datenbank mit Code First verwenden können. Nachdem Sie die Tools installiert haben, werden einige zusätzliche Optionen in Kontextmenüs angezeigt. Wenn Sie beispielsweise mit der rechten Maustaste auf Ihre Kontextklasse in Projektmappen-Explorer klicken, wird die Entity Framework-Option angezeigt. Dadurch können Sie ein Diagramm generieren. Wenn Sie Code First verwenden, können Sie das Datenmodell im Diagramm nicht ändern, aber Sie können Dinge verschieben, um das Verständnis zu erleichtern.

EF-Diagramm

Entity Framework-Quellcode

Der Quellcode für Entity Framework 6 ist auf GitHub verfügbar. Sie können Fehler dateiieren, und Sie können Ihre eigenen Verbesserungen am EF-Quellcode beitragen.

Obwohl der Quellcode offen ist, wird Entity Framework als Microsoft-Produkt vollständig unterstützt. Das Microsoft Entity Framework-Team überprüft, welche Beiträge akzeptiert werden. Es testet alle Codeänderungen, um die Qualität jedes Release zu garantieren.

Danksagungen

  • Tom Dykstra hat die ursprüngliche Version dieses Tutorials geschrieben, das EF 5-Update mitverfasst und das EF 6-Update geschrieben. Tom ist leitender Programmierautor im Microsoft Web Platform and Tools Content Team.
  • Rick Anderson (twitter @RickAndMSFT) hat die meiste Arbeit an der Aktualisierung des Tutorials für EF 5 und MVC 4 ausgeführt und das EF 6-Update mitverfasst. Rick ist ein leitender Programmierautor für Microsoft, der sich auf Azure und MVC konzentriert.
  • Rowan Miller und andere Mitglieder des Entity Framework-Teams halfen bei code reviews und halfen beim Debuggen vieler Probleme mit Migrationen, die beim Aktualisieren des Tutorials für EF 5 und EF 6 aufgetreten sind.

Problembehandlung für häufige Fehler

Erstellen/Schattenkopie nicht möglich

Fehlermeldung:

"Dateiname>"< kann nicht erstellt/schattenkopiert werden, wenn diese Datei bereits vorhanden ist.

Lösung

Warten Sie einige Sekunden, und aktualisieren Sie die Seite.

Update-Database nicht erkannt

Fehlermeldung (vom Update-Database Befehl im PMC):

Der Begriff "Update-Database" wird nicht als Name eines Cmdlets, einer Funktion, einer Skriptdatei oder eines bedienbaren Programms erkannt. Prüfen Sie die Schreibweise des Namens bzw. stellen Sie sicher, dass der Pfad korrekt angegeben wurde, und versuchen Sie es erneut.

Lösung

Beenden Sie Visual Studio. Öffnen Sie das Projekt erneut, und versuchen Sie es erneut.

Fehler bei der Überprüfung

Fehlermeldung (vom Update-Database Befehl im PMC):

Fehler bei der Überprüfung für mindestens eine Entität. Weitere Informationen finden Sie unter "EntityValidationErrors"-Eigenschaft.

Lösung

Eine Ursache für dieses Problem sind Validierungsfehler, wenn die Seed Methode ausgeführt wird. Tipps zum Debuggen der Seed Methode finden Sie unter Seeding and Debugging Entity Framework (EF)-DBs.

HTTP 500.19-Fehler

Fehlermeldung:

HTTP-Fehler 500.19 – Interner Serverfehler Auf die angeforderte Seite kann nicht zugegriffen werden, da die zugehörigen Konfigurationsdaten für die Seite ungültig sind.

Lösung

Eine Möglichkeit, diesen Fehler zu erhalten, besteht darin, mehrere Kopien der Lösung zu haben, die jeweils die gleiche Portnummer verwenden. Sie können dieses Problem in der Regel lösen, indem Sie alle Instanzen von Visual Studio beenden und dann das Projekt neu starten, an dem Sie arbeiten. Wenn dies nicht funktioniert, versuchen Sie, die Portnummer zu ändern. Klicken Sie mit der rechten Maustaste auf die Projektdatei, und klicken Sie dann auf Eigenschaften. Wählen Sie die Registerkarte Web aus, und ändern Sie dann die Portnummer im Textfeld Projekt-URL .

Fehler beim Bestimmen der SQL Server-Instanz

Fehlermeldung:

Ein netzwerkbezogener oder instanzspezifischer Fehler beim Herstellen einer Verbindung mit SQL Server. Der Server wurde nicht gefunden, oder auf ihn kann nicht zugegriffen werden. Stellen Sie sicher, dass der Instanzname richtig und SQL Server so konfiguriert ist, das Remoteverbindungen zulässig sind. (Anbieter: SQL-Netzwerkschnittstellen, Fehler: 26 – Fehler beim Auffinden des/der angegebenen Servers/Instanz.)

Lösung

Überprüfen Sie die Verbindungszeichenfolge. Wenn Sie die Datenbank manuell gelöscht haben, ändern Sie den Namen der Datenbank in der Konstruktionszeichenfolge.

Abrufen des Codes

Abgeschlossenes Projekt herunterladen

Zusätzliche Ressourcen

Weitere Informationen zum Arbeiten mit Daten mithilfe von Entity Framework finden Sie auf der EF-Dokumentationsseite auf MSDN und ASP.NET Datenzugriff – Empfohlene Ressourcen.

Weitere Informationen zum Bereitstellen Ihrer Webanwendung, nachdem Sie sie erstellt haben, finden Sie unter ASP.NET Webbereitstellung – Empfohlene Ressourcen in der MSDN Library.

Informationen zu anderen Themen im Zusammenhang mit MVC, z. B. Authentifizierung und Autorisierung, finden Sie unter ASP.NET MVC – Empfohlene Ressourcen.

Nächste Schritte

In diesem Tutorial:

  • Haben Sie unformatierte SQL-Abfragen durchgeführt
  • Keine Nachverfolgungsabfragen ausgeführt
  • Überprüfte SQL-Abfragen, die an die Datenbank gesendet werden

Außerdem haben Sie Folgendes kennengelernt:

  • Erstellen einer Abstraktionsebene
  • Proxyklassen
  • Automatische Änderungserkennung
  • Automatische Validierung
  • Entity Framework Power Tools
  • Entity Framework-Quellcode

Dadurch wird diese Reihe von Tutorials zur Verwendung von Entity Framework in einer ASP.NET MVC-Anwendung abgeschlossen. Wenn Sie mehr über EF Database First erfahren möchten, lesen Sie die Tutorialreihe DB First.