Część 2. Tworzenie modeli domeny

Autor: Rick Anderson

Pobieranie ukończonego projektu

Dodawanie modeli

Istnieją trzy sposoby podejścia do programu Entity Framework:

  • Najpierw baza danych: zaczynasz od bazy danych, a program Entity Framework generuje kod.
  • Najpierw model: zaczynasz od modelu wizualnego, a platforma Entity Framework generuje zarówno bazę danych, jak i kod.
  • Code-first: zaczynasz od kodu, a program Entity Framework generuje bazę danych.

Używamy podejścia opartego na kodzie, więc zaczynamy od zdefiniowania obiektów domeny jako obiektów POC (zwykłych obiektów CLR). W przypadku podejścia opartego na kodzie obiekty domeny nie wymagają dodatkowego kodu do obsługi warstwy bazy danych, takich jak transakcje lub trwałość. (W szczególności nie muszą dziedziczyć z klasy EntityObject ). Nadal można używać adnotacji danych do kontrolowania sposobu tworzenia schematu bazy danych przez program Entity Framework.

Ponieważ obiekty POCO nie zawierają żadnych dodatkowych właściwości opisujących stan bazy danych, można je łatwo serializować do formatu JSON lub XML. Nie oznacza to jednak, że zawsze należy uwidaczniać modele programu Entity Framework bezpośrednio dla klientów, jak zobaczymy w dalszej części tego samouczka.

Utworzymy następujące obiekty POCO:

  • produkt
  • Zamówienie
  • Szczegóły zamówienia

Aby utworzyć każdą klasę, kliknij prawym przyciskiem myszy folder Models w Eksploratorze rozwiązań. Z menu kontekstowego wybierz pozycję Dodaj , a następnie wybierz pozycję Klasa.

Zrzut ekranu przedstawiający menu Eksplorator rozwiązań dla folderu Modele. Menu Dodaj jest otwarte, a opcja Klasa jest wyróżniona.

Dodaj klasę z następującą implementacją Product :

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; }
    }
}

Zgodnie z konwencją platforma Entity Framework używa Id właściwości jako klucza podstawowego i mapuje ją na kolumnę tożsamości w tabeli bazy danych. Podczas tworzenia nowego Product wystąpienia nie ustawisz wartości parametru Id, ponieważ baza danych generuje wartość.

Atrybut ScaffoldColumn informuje ASP.NET MVC, aby pominąć właściwość Id podczas generowania formularza do edycji. Wymagany atrybut służy do weryfikowania modelu. Określa, że Name właściwość musi być ciągiem niepustym.

Dodaj klasę Order :

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; }
    }
}

Dodaj klasę OrderDetail :

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; }
    }
}

Stosunki kluczowe dla spraw zagranicznych

Zamówienie zawiera wiele szczegółów zamówienia, a każdy szczegół zamówienia odnosi się do jednego produktu. Aby reprezentować te relacje, OrderDetail klasa definiuje właściwości o nazwach OrderId i ProductId. Program Entity Framework wywnioskuje, że te właściwości reprezentują klucze obce i doda ograniczenia klucza obcego do bazy danych.

Zrzut ekranu przedstawiający menu programu Visual Studio dla klas Orders, Products i OrderDetails.

Klasy Order i OrderDetail zawierają również właściwości "nawigacji", które zawierają odwołania do powiązanych obiektów. Mając dane zamówienie, możesz przejść do produktów w tym zamówieniu, korzystając z właściwości nawigacyjnych.

Skompiluj teraz projekt. Program Entity Framework używa odbicia w celu odnalezienia właściwości modeli, dlatego wymaga skompilowanego zestawu do utworzenia schematu bazy danych.

Konfigurowanie formaterów Media-Type

Formater typu media to obiekt, który serializuje dane, kiedy interfejs API zapisuje treść odpowiedzi HTTP. Wbudowane formatery obsługują dane wyjściowe JSON i XML. Domyślnie oba te formatery serializują wszystkie obiekty według wartości.

Serializacja według wartości powoduje problem, jeśli graf obiektu zawiera odwołania cykliczne. Jest to dokładnie przypadek klas Order i OrderDetail , ponieważ każda z nich zawiera odwołanie do drugiego. Program formatujący będzie postępować zgodnie z odwołaniami, zapisywać każdy obiekt według wartości i przechodzić w okręgi. W związku z tym musimy zmienić domyślne zachowanie.

W Eksploratorze rozwiązań rozwiń folder App_Start i otwórz plik o nazwie WebApiConfig.cs. Dodaj następujący kod do WebApiConfig klasy:

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);
    }
}

Ten kod konfiguruje formater JSON do zachowywania odwołań do obiektów i całkowicie usuwa formater XML z potoku. (Można skonfigurować formater XML w celu zachowania odwołań do obiektów, ale jest to nieco więcej pracy i potrzebujemy tylko kodu JSON dla tej aplikacji. Aby uzyskać więcej informacji, zobacz Obsługa odwołań do obiektów cyklicznych).