Freigeben über


Teil 2: Erstellen der Domänenmodelle

von Rick Anderson

Abgeschlossenes Projekt herunterladen

Modelle hinzufügen

Es gibt drei Möglichkeiten, mit dem Entity Framework umzugehen:

  • Datenbank zuerst: Sie beginnen mit einer Datenbank, und Entity Framework generiert den Code.
  • Modell zuerst: Sie beginnen mit einem visuellen Modell, und Entity Framework generiert sowohl die Datenbank als auch den Code.
  • Code zuerst: Sie beginnen mit Code, und Entity Framework generiert die Datenbank.

Wir verwenden den Code-first-Ansatz, daher definieren wir zunächst unsere Domänenobjekte als POCOs (einfache CLR-Objekte). Bei dem Code-first-Ansatz benötigen Domänenobjekte keinen zusätzlichen Code, um die Datenbankebene zu unterstützen, z. B. Transaktionen oder Persistenz. (Insbesondere müssen sie nicht von der EntityObject-Klasse erben.) Sie können weiterhin Datenanmerkungen verwenden, um zu steuern, wie Entity Framework das Datenbankschema erstellt.

Da POCOs keine zusätzlichen Eigenschaften enthalten, die den Datenbankstatus beschreiben, können sie problemlos in JSON oder XML serialisiert werden. Das bedeutet jedoch nicht, dass Sie Ihre Entity Framework-Modelle immer direkt für Clients verfügbar machen sollten, wie es weiter unten im Lernprogramm zu sehen ist.

Wir erstellen die folgenden POCOs:

  • Produkt
  • Bestellung
  • Bestelldetail

Um jede Klasse zu erstellen, klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Ordner "Modelle". Wählen Sie im Kontextmenü "Hinzufügen" und dann "Klasse" aus.

Screenshot des Menüs

Fügen Sie eine Product Klasse mit der folgenden Implementierung hinzu:

namespace ProductStore.Models
{
    using System.ComponentModel.DataAnnotations;

    public class Product
    {
        [ScaffoldColumn(false)]
        public int Id { get; set; }
        [Required]
        public string Name { get; set; }
        public decimal Price { get; set; }
        public decimal ActualCost { get; set; }
    }
}

Standardmäßig verwendet Entity Framework die Id Eigenschaft als Primärschlüssel und ordnet sie einer Identitätsspalte in der Datenbanktabelle zu. Wenn Sie eine neue Product Instanz erstellen, legen Sie keinen Wert fest für Id, da die Datenbank den Wert generiert.

Das ScaffoldColumn-Attribut weist ASP.NET MVC an, die Id Eigenschaft beim Generieren eines Editorformulars zu überspringen. Das Erforderliche Attribut wird verwendet, um das Modell zu überprüfen. Es gibt an, dass die Name Eigenschaft eine nicht leere Zeichenfolge sein muss.

Fügen Sie die Order Klasse hinzu:

namespace ProductStore.Models
{
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;

    public class Order
    {
        public int Id { get; set; }
        [Required]
        public string Customer { get; set; }

        // Navigation property
        public  ICollection<OrderDetail> OrderDetails { get; set; }
    }
}

Fügen Sie die OrderDetail Klasse hinzu:

namespace ProductStore.Models
{
    public class OrderDetail
    {
        public int Id { get; set; }
        public int Quantity { get; set; }
        public int OrderId { get; set; }
        public int ProductId { get; set; }

        // Navigation properties
        public Product Product { get; set; }
        public Order Order { get; set; }
    }
}

Fremdschlüsselbeziehungen

Eine Bestellung enthält viele Bestelldetails, und jedes Bestelldetail bezieht sich auf ein einzelnes Produkt. Um diese Beziehungen darzustellen, definiert die OrderDetail Klasse die Eigenschaften OrderId und ProductId. Entity Framework leitet ab, dass diese Eigenschaften Fremdschlüssel darstellen und Fremdschlüsseleinschränkungen zur Datenbank hinzufügen.

Screenshot der Visual Studio-Menüs für die Klassen

Die Order Klassen OrderDetail enthalten auch "Navigationseigenschaften", die Verweise auf die zugehörigen Objekte enthalten. Bei einer Bestellung können Sie zu den Produkten in der Bestellung navigieren, indem Sie den Navigationsattributen folgen.

Kompilieren Sie das Projekt jetzt. Entity Framework verwendet Reflektion, um die Eigenschaften der Modelle zu ermitteln, sodass eine kompilierte Assembly zum Erstellen des Datenbankschemas erforderlich ist.

Konfigurieren der Media-Type-Formatierer

Ein Medientypformatierer ist ein Objekt, das Ihre Daten serialisiert, wenn die Web-API den HTTP-Antworttext schreibt. Die integrierten Formatierer unterstützen JSON- und XML-Ausgabe. Standardmäßig serialisieren beide Formatierer alle Objekte nach Wert.

Die Serialisierung nach Wert verursacht ein Problem, wenn ein Objektdiagramm Zirkelbezüge enthält. Das ist genau der Fall bei den Order Klassen, OrderDetail da jeder einen Verweis auf die andere enthält. Der Formatierer folgt den Verweisen, schreibt jedes Objekt anhand seines Werts und dreht sich im Kreis. Daher müssen wir das Standardverhalten ändern.

Erweitern Sie im Projektmappen-Explorer den Ordner App_Start, und öffnen Sie die Datei mit dem Namen WebApiConfig.cs. Fügen Sie der WebApiConfig-Klasse folgenden Code hinzu:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        // New code:
        var json = config.Formatters.JsonFormatter;
        json.SerializerSettings.PreserveReferencesHandling =
            Newtonsoft.Json.PreserveReferencesHandling.Objects;

        config.Formatters.Remove(config.Formatters.XmlFormatter);
    }
}

Mit diesem Code wird der JSON-Formatierer so festgelegt, dass Objektverweise erhalten bleiben, und der XML-Formatierer wird vollständig aus der Pipeline entfernt. (Sie können den XML-Formatierer so konfigurieren, dass Objektverweise erhalten bleiben, aber es ist etwas mehr Arbeit, und wir benötigen nur JSON für diese Anwendung. Weitere Informationen finden Sie unter Behandeln von Zirkelobjektverweise.)