Udostępnij za pośrednictwem


Dziedziczenie TPH w projektowaniu

W tym przewodniku krok po kroku pokazano, jak zaimplementować dziedziczenie typu tabela na hierarchię (TPH) w modelu koncepcyjnym za pomocą projektanta Entity Framework (EF Designer). Dziedziczenie TPH używa jednej tabeli bazy danych do obsługi danych dla wszystkich typów jednostek w hierarchii dziedziczenia.

W tym przewodniku odwzorujemy tabelę Person na trzy typy encji: Person (typ podstawowy), Student (pochodzi od Person) i Instruktor (pochodzi od Person). Utworzymy model koncepcyjny z bazy danych (Database First), a następnie zmienimy model w celu zaimplementowania dziedziczenia TPH przy użyciu projektanta EF.

Istnieje możliwość mapowania dziedziczenia TPH przy użyciu podejścia Model-First, ale konieczne byłoby napisanie własnego przepływu pracy do generowania bazy danych, który jest złożony. Następnie należy przypisać ten przepływ pracy do właściwości Przepływ pracy generowania bazy danych w projektancie EF. Łatwiejszą alternatywą jest użycie funkcji Code First.

Inne opcje dziedziczenia

Tabela na typ (TPT) to inny typ dziedziczenia, w którym oddzielne tabele w bazie danych są mapowane na jednostki, które uczestniczą w dziedziczeniu.  Aby uzyskać informacje na temat mapowania dziedziczenia tabeli na typ za pomocą projektanta EF, zobacz Dziedziczenie TPT programu EF Designer.

Modele dziedziczenia tabela-na-konkretny-typ (TPC) i mieszane modele dziedziczenia są obsługiwane przez środowisko uruchomieniowe Entity Framework, ale nie są obsługiwane przez projektanta EF. Jeśli chcesz użyć TPC lub dziedziczenia mieszanego, masz dwie opcje: użyj funkcji Code First lub ręcznie edytuj plik EDMX. Jeśli zdecydujesz się pracować z plikiem EDMX, okno Szczegóły mapowania zostanie umieszczone w trybie awaryjnym i nie będzie można użyć projektanta do zmiany mapowań.

Wymagania wstępne

Aby ukończyć ten przewodnik, potrzebne są następujące elementy:

Konfigurowanie projektu

  • Otwórz program Visual Studio 2012.
  • Wybierz Plik — Nowy —>> Projekt
  • W okienku po lewej stronie kliknij pozycję Visual C#, a następnie wybierz szablon Konsola .
  • Wprowadź TPHDBFirstSample jako nazwę.
  • Kliknij przycisk OK.

Tworzenie modelu

  • Kliknij prawym przyciskiem myszy nazwę projektu w Eksploratorze rozwiązań, a następnie wybierz polecenie Dodaj —> nowy element.
  • Wybierz pozycję Dane z menu po lewej stronie, a następnie wybierz pozycję ADO.NET Model danych jednostki w okienku Szablony.
  • Wprowadź ciąg TPHModel.edmx jako nazwę pliku, a następnie kliknij przycisk Dodaj.
  • W oknie dialogowym Wybieranie zawartości modelu wybierz pozycję Generuj z bazy danych, a następnie kliknij przycisk Dalej.
  • Kliknij pozycję Nowe połączenie. W oknie dialogowym Właściwości połączenia wprowadź nazwę serwera (na przykład (localdb)\mssqllocaldb), wybierz metodę uwierzytelniania, wpisz School jako nazwę bazy danych, a następnie kliknij przycisk OK. Okno dialogowe Wybór połączenia danych jest zaktualizowane z ustawieniem połączenia z bazą danych.
  • W oknie dialogowym Wybieranie obiektów bazy danych w węźle Tabele wybierz tabelę Person .
  • Kliknij przycisk Zakończ.

Zostanie wyświetlony projektant jednostek, który udostępnia powierzchnię projektową do edycji modelu. Wszystkie obiekty wybrane w oknie dialogowym Wybieranie obiektów bazy danych są dodawane do modelu.

W ten sposób tabela Person wygląda w bazie danych.

Tabela osób  

Implementowanie dziedziczenia typu Table-per-Hierarchy

Tabela Person zawiera kolumnę Dyskryminująca , która może mieć jedną z dwóch wartości: "Student" i "Instruktor". W zależności od wartości tabela Person zostanie zamapowana na jednostkę Student lub jednostkę Instruktor . Tabela Person zawiera również dwie kolumny HireDate i EnrollmentDate, które muszą mieć wartość null , ponieważ osoba nie może być studentem i instruktorem w tym samym czasie (przynajmniej nie w tym przewodniku).

Dodawanie nowych jednostek

  • Dodaj nową jednostkę. Aby to zrobić, kliknij prawym przyciskiem myszy puste miejsce powierzchni projektowej Projektanta programu Entity Framework i wybierz polecenie Dodaj jednostkę>.
  • Wpisz Instruktordla nazwy jednostki i wybierz pozycję Osoba z listy rozwijanej dla typu podstawowego.
  • Kliknij przycisk OK.
  • Dodaj kolejną nową jednostkę. Wpisz Student jako nazwę jednostki i wybierz pozycję Osoba z listy rozwijanej dla typu podstawowego.

Do powierzchni projektowej dodano dwa nowe typy jednostek. Strzałka wskazuje z nowych typów jednostek na typ jednostki Person ; Oznacza to, że osoba jest typem podstawowym dla nowych typów jednostek.

  • Kliknij prawym przyciskiem myszy na właściwość HireDate encji Person. Wybierz pozycję Wytnij (lub użyj klucza Ctrl-X).
  • Kliknij prawym przyciskiem myszy jednostkę Instruktor i wybierz polecenie Wklej (lub użyj klucza Ctrl-V).
  • Kliknij prawym przyciskiem myszy właściwość HireDate i wybierz pozycję Właściwości.
  • W oknie Właściwości ustaw właściwość Nullable na false.
  • Kliknij prawym przyciskiem myszy właściwość EnrollmentDate encji Person. Wybierz pozycję Wytnij (lub użyj klucza Ctrl-X).
  • Kliknij prawym przyciskiem myszy jednostkę Student i wybierz polecenie Wklej (lub użyj klucza Ctrl-V).
  • Wybierz właściwość EnrollmentDate i ustaw właściwość Nullable na false.
  • Wybierz typ jednostki Osoba . W oknie Właściwości ustaw właściwość Abstract na true.
  • Usuń właściwość dyskryminującą z person. Przyczyną jego usunięcia jest objaśniona w poniższej sekcji.

Mapowanie jednostek

  • Kliknij prawym przyciskiem myszy instruktora i wybierz pozycję Mapowanie tabeli. Jednostka Instruktor jest zaznaczona w oknie Szczegóły mapowania.

  • Kliknij <Dodaj tabelę lub widok> w oknie Szczegóły mapowania. Pole <Dodawanie tabeli lub widoku> staje się listą rozwijaną tabel lub widoków, do których można mapować wybraną jednostkę.

  • Wybierz pozycję Osoba z listy rozwijanej.

  • Okno Szczegóły mapowania zostało zaktualizowane przy użyciu domyślnych mapowań kolumn i opcji dodawania warunku.

  • Kliknij pozycję <Dodaj warunek>. Pole <Dodawanie warunku> staje się listą rozwijaną kolumn, dla których można ustawić warunki.

  • Z listy rozwijanej wybierz pozycję Dyskryminator .

  • W kolumnie Operator okna Szczegóły mapowania wybierz pozycję = z listy rozwijanej.

  • W kolumnie Wartość/Właściwość wpisz Instruktor. Wynik końcowy powinien wyglądać następująco:

    Szczegóły mapowania

  • Powtórz te kroki dla typu jednostki Student , ale ustaw warunek na wartość Student .
    Powodem, dla którego chcieliśmy usunąć właściwość Dyskryminator , jest to, że nie można mapować kolumny tabeli więcej niż raz. Ta kolumna będzie używana do mapowania warunkowego, więc nie można jej również używać do mapowania właściwości. Jedynym sposobem, w jaki można go użyć w obu przypadkach, jest to, jeśli warunek używa porównania Is Null lub Is Not Null.

Dziedziczenie „table-per-hierarchy” zostało teraz zaimplementowane.

Końcowy TPH

Korzystanie z modelu

Otwórz plik Program.cs , w którym zdefiniowano metodę Main . Wklej następujący kod do funkcji Main . Kod wykonuje trzy zapytania. Pierwsze zapytanie przywraca wszystkie obiekty Person . Drugie zapytanie używa metody OfType do zwracania obiektów instruktora . Trzecie zapytanie używa metody OfType do zwracania obiektów Student .

    using (var context = new SchoolEntities())
    {
        Console.WriteLine("All people:");
        foreach (var person in context.People)
        {
            Console.WriteLine("    {0} {1}", person.FirstName, person.LastName);
        }

        Console.WriteLine("Instructors only: ");
        foreach (var person in context.People.OfType<Instructor>())
        {
            Console.WriteLine("    {0} {1}", person.FirstName, person.LastName);
        }

        Console.WriteLine("Students only: ");
        foreach (var person in context.People.OfType<Student>())
        {
            Console.WriteLine("    {0} {1}", person.FirstName, person.LastName);
        }
    }