Udostępnij za pośrednictwem


Kod pierwszy do nowej bazy danych

Ten film wideo i przewodnik krok po kroku zawierają wprowadzenie do programowania Code First przeznaczonego dla nowej bazy danych. Ten scenariusz obejmuje celowanie w bazę danych, którą Code First utworzy, jeśli nie istnieje, lub pustą bazę danych, do której Code First doda nowe tabele. Funkcja Code First umożliwia zdefiniowanie modelu przy użyciu klas języka C# lub VB.Net. Dodatkową konfigurację można opcjonalnie wykonać przy użyciu atrybutów w klasach i właściwościach lub przy użyciu płynnego interfejsu API.

Obejrzyj film wideo

Ten film wideo zawiera wprowadzenie do programowania Code First przeznaczonego dla nowej bazy danych. Ten scenariusz obejmuje celowanie w bazę danych, która nie istnieje i zostanie utworzona przez Code First, lub w pustą bazę danych, do której Code First doda nowe tabele. Funkcja Code First umożliwia zdefiniowanie modelu przy użyciu klas języka C# lub VB.Net. Dodatkową konfigurację można opcjonalnie wykonać przy użyciu atrybutów w klasach i właściwościach lub przy użyciu płynnego interfejsu API.

Prezentowane przez: Rowan Miller

Wideo: WMV | MP4 | WMV (ZIP)

Wymagania wstępne

Aby ukończyć ten przewodnik, musisz mieć zainstalowany co najmniej program Visual Studio 2010 lub Visual Studio 2012.

Jeśli używasz programu Visual Studio 2010, musisz również zainstalować pakiet NuGet .

1. Tworzenie aplikacji

Aby zachować prostotę, utworzymy podstawową aplikację konsolową, która używa funkcji Code First do wykonywania dostępu do danych.

  • Otwórz program Visual Studio.
  • Plik — Nowy —>> Projekt...
  • Wybierz pozycję Windows z menu po lewej stronie i pozycję Aplikacja konsolowa
  • Wprowadź codeFirstNewDatabaseSample jako nazwę
  • Wybierz OK

2. Tworzenie modelu

Zdefiniujmy bardzo prosty model przy użyciu klas. Definiujemy je tylko w pliku Program.cs, ale w rzeczywistej aplikacji można podzielić klasy na oddzielne pliki i potencjalnie oddzielny projekt.

Poniżej definicji klasy Program w Program.cs dodaj następujące dwie klasy.

public class Blog
{
    public int BlogId { get; set; }
    public string Name { get; set; }

    public virtual List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int BlogId { get; set; }
    public virtual Blog Blog { get; set; }
}

Zauważysz, że tworzymy dwie wirtualne właściwości nawigacji (Blog.Posts i Post.Blog). Umożliwia to funkcję ładowania z opóźnieniem w programie Entity Framework. Ładowanie leniwe oznacza, że zawartość tych właściwości zostanie automatycznie załadowana z bazy danych podczas próby uzyskania do nich dostępu.

3. Tworzenie kontekstu

Teraz nadszedł czas, aby zdefiniować kontekst pochodny, który reprezentuje sesję z bazą danych, umożliwiając nam wykonywanie zapytań i zapisywanie danych. Definiujemy kontekst pochodzący od System.Data.Entity.DbContext i udostępniający typizowany DbSet dla każdej klasy w naszym modelu.

Teraz zaczynamy używać typów z programu Entity Framework, dlatego musimy dodać pakiet NuGet EntityFramework.

  • Projekt —> zarządzanie pakietami NuGet... Uwaga: Jeśli nie masz opcji Zarządzaj pakietami NuGet... należy zainstalować najnowszą wersję pakietu NuGet
  • Wybierz kartę Online
  • Wybierz pakiet EntityFramework
  • Kliknij pozycję Zainstaluj

Dodaj dyrektywę using dla System.Data.Entity na początku Program.cs.

using System.Data.Entity;

Poniżej klasy Post w Program.cs dodaj następujący kontekst pochodny.

public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
}

Oto pełna lista elementów, które powinny teraz zawierać Program.cs.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;

namespace CodeFirstNewDatabaseSample
{
    class Program
    {
        static void Main(string[] args)
        {
        }
    }

    public class Blog
    {
        public int BlogId { get; set; }
        public string Name { get; set; }

        public virtual List<Post> Posts { get; set; }
    }

    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }

        public int BlogId { get; set; }
        public virtual Blog Blog { get; set; }
    }

    public class BloggingContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
    }
}

To jest cały kod, którego potrzebujemy, aby zacząć przechowywać i pobierać dane. Oczywiście za kulisami dzieje się sporo i przyjrzymy się temu w ciągu chwili, ale najpierw zobaczmy to w akcji.

4. Odczytywanie i zapisywanie danych

Zaimplementuj metodę Main w Program.cs, jak pokazano poniżej. Ten kod tworzy nowe wystąpienie kontekstu, a następnie używa go do wstawienia nowego bloga. Następnie używa zapytania LINQ, aby pobrać wszystkie blogi z bazy danych uporządkowane alfabetycznie według tytułu.

class Program
{
    static void Main(string[] args)
    {
        using (var db = new BloggingContext())
        {
            // Create and save a new Blog
            Console.Write("Enter a name for a new Blog: ");
            var name = Console.ReadLine();

            var blog = new Blog { Name = name };
            db.Blogs.Add(blog);
            db.SaveChanges();

            // Display all Blogs from the database
            var query = from b in db.Blogs
                        orderby b.Name
                        select b;

            Console.WriteLine("All blogs in the database:");
            foreach (var item in query)
            {
                Console.WriteLine(item.Name);
            }

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }
}

Teraz możesz uruchomić aplikację i przetestować ją.

Enter a name for a new Blog: ADO.NET Blog
All blogs in the database:
ADO.NET Blog
Press any key to exit...

Gdzie są moje dane?

Zgodnie z konwencją, to DbContext utworzył bazę danych dla ciebie.

  • Jeśli lokalne wystąpienie programu SQL Express jest dostępne (domyślnie zainstalowane w programie Visual Studio 2010), program Code First utworzył bazę danych w tym wystąpieniu
  • Jeśli usługa SQL Express nie jest dostępna, program Code First spróbuje użyć bazy danych LocalDB (domyślnie zainstalowanej w programie Visual Studio 2012)
  • Baza danych jest nazwana po w pełni kwalifikowanej nazwie kontekstu pochodnego, w naszym przypadku jest to CodeFirstNewDatabaseSample.BloggingContext

Są to tylko konwencje domyślne i istnieją różne sposoby zmiany bazy danych używanej przez program Code First. Więcej informacji można znaleźć w temacie How DbContext Discovers the Model and Database Connection (Jak narzędzie DbContext odnajduje model i połączenie z bazą danych ). Możesz nawiązać połączenie z tą bazą danych przy użyciu Eksploratora serwera w programie Visual Studio

  • Widok —> Eksplorator serwera

  • Kliknij prawym przyciskiem myszy pozycję Połączenia danych i wybierz pozycję Dodaj połączenie...

  • Jeśli wcześniej nie łączyłeś się z bazą danych za pomocą Eksploratora serwera, musisz wybrać Microsoft SQL Server jako źródło danych.

    Wybieranie źródła danych

  • Połącz się z bazą danych LocalDB lub SQL Express, w zależności od zainstalowanej bazy danych

Teraz możemy sprawdzić schemat utworzony przez program Code First.

Początkowy schemat

DbContext wypracował klasy, które należy uwzględnić w modelu, przeglądając zdefiniowane przez nas właściwości DbSet. Następnie używa domyślnego zestawu konwencji Code First do określania nazw tabel i kolumn, określania typów danych, znajdowania kluczy podstawowych itp. W dalszej części tego przewodnika przyjrzymy się temu, jak można zastąpić te konwencje.

5. Radzenie sobie ze zmianami modelu

Teraz nadszedł czas, aby wprowadzić pewne zmiany w naszym modelu, gdy wprowadzimy te zmiany, musimy również zaktualizować schemat bazy danych. W tym celu użyjemy funkcji o nazwie Migracje code first, w skrócie Migracje.

Migracje umożliwiają nam uporządkowany zestaw kroków opisujących sposób uaktualniania (i obniżania poziomu) schematu bazy danych. Każdy z tych kroków, znany jako migracja, zawiera kod opisujący zmiany, które mają zostać zastosowane. 

Pierwszym krokiem jest aktywacja Code First Migrations dla naszego kontekstu BloggingContext.

  • Narzędzia —> Menedżer pakietów biblioteki —> konsola menedżera pakietów

  • Uruchom polecenie Enable-Migrations w konsoli menedżera pakietów

  • Nowy folder Migrations został dodany do naszego projektu, który zawiera dwa elementy:

    • Configuration.cs — ten plik zawiera ustawienia, których Migration będą używać do migrowania BloggingContext. Nie musimy nic zmieniać w tym przewodniku, ale tutaj można określić dane inicjujące, zarejestrować dostawców innych baz danych, zmienić przestrzeń nazw, w której są generowane migracje itp.
    • <timestamp>_InitialCreate.cs — jest to pierwsza migracja, która reprezentuje zmiany, jakie zostały już zastosowane do bazy danych, aby zmienić ją z pustej bazy danych na taką, która zawiera tabele Blogi i Wpisy. Mimo że Code First automatycznie utworzyło te tabele dla nas, teraz, gdy zdecydowaliśmy się na migracje, zostały one przekształcone w migrację. Program Code First zarejestrował również w lokalnej bazie danych, że ta migracja została już zastosowana. Sygnatura czasowa w nazwie pliku jest używana do celów porządkowania.

    Teraz wprowadźmy zmianę w naszym modelu, dodajmy właściwość Url do klasy Blog:

public class Blog
{
    public int BlogId { get; set; }
    public string Name { get; set; }
    public string Url { get; set; }

    public virtual List<Post> Posts { get; set; }
}
  • Uruchom polecenie Add-Migration AddUrl w konsoli menedżera pakietów. Polecenie Add-Migration sprawdza zmiany od ostatniej migracji i tworzy nowy szablon migracji z wszelkimi znalezionymi zmianami. Możemy nadać migracjom nazwę; w tym przypadku nazywamy migrację „AddUrl”. Kod szkieletowy informuje, że musimy dodać kolumnę Url, która może przechowywać dane typu string, do tabeli dbo.Blogs. W razie potrzeby możemy edytować kod szkieletowy, ale nie jest to wymagane w tym przypadku.
namespace CodeFirstNewDatabaseSample.Migrations
{
    using System;
    using System.Data.Entity.Migrations;

    public partial class AddUrl : DbMigration
    {
        public override void Up()
        {
            AddColumn("dbo.Blogs", "Url", c => c.String());
        }

        public override void Down()
        {
            DropColumn("dbo.Blogs", "Url");
        }
    }
}
  • Uruchom polecenie Update-Database w konsoli menedżera pakietów. To polecenie spowoduje zatwierdzenie wszelkich oczekujących migracji do bazy danych. Nasza migracja InitialCreate została już zastosowana, więc migracje będą po prostu stosować naszą nową migrację addUrl. Porada: podczas wywoływania polecenia Update-Database można użyć przełącznika –Verbose, aby zobaczyć instrukcje SQL wykonywane na bazie danych.

Nowa kolumna Url jest teraz dodawana do tabeli Blogs w bazie danych:

Schemat z adresem URL

6. Adnotacje danych

Do tej pory po prostu pozwoliliśmy EF odnajdywać model przy użyciu jego domyślnych konwencji, ale zdarzają się sytuacje, kiedy nasze klasy nie przestrzegają konwencji i konieczna będzie dalsza konfiguracja. Istnieją dwie opcje dla tego; W tej sekcji przyjrzymy się adnotacjom danych, a następnie płynnego interfejsu API w następnej sekcji.

  • Dodajmy klasę User do naszego modelu
public class User
{
    public string Username { get; set; }
    public string DisplayName { get; set; }
}
  • Musimy również dodać zbiór do naszego wyprowadzonego kontekstu
public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
    public DbSet<User> Users { get; set; }
}
  • Jeśli spróbowalibyśmy dodać migrację, pojawiłby się błąd z informacją "EntityType 'Użytkownik' nie ma zdefiniowanego klucza. Zdefiniuj klucz dla tego typu jednostki." ponieważ EF nie może wiedzieć, że nazwa użytkownika powinna być kluczem podstawowym dla Użytkownik.
  • Teraz użyjemy Data Annotations, więc musimy dodać instrukcję using w górnej części Program.cs
using System.ComponentModel.DataAnnotations;
  • Teraz dodaj adnotację do właściwości Username, aby zidentyfikować, że jest to klucz podstawowy
public class User
{
    [Key]
    public string Username { get; set; }
    public string DisplayName { get; set; }
}
  • Użyj polecenia Add-Migration AddUser, aby stworzyć szkielet migracji i zastosować te zmiany do bazy danych.
  • Uruchom polecenie Update-Database , aby zastosować nową migrację do bazy danych

Nowa tabela jest teraz dodawana do bazy danych:

Schemat z użytkownikami

Pełna lista adnotacji obsługiwanych przez program EF to:

7. Interfejs API Fluent

W poprzedniej sekcji przyjrzeliśmy się używaniu adnotacji danych w celu uzupełnienia lub zastąpienia wykrytych przez konwencję elementów. Innym sposobem skonfigurowania modelu jest użycie interfejsu API Code First fluent.

Większość konfiguracji modelu można wykonać przy użyciu prostych adnotacji danych. Fluent API to bardziej zaawansowany sposób określania konfiguracji modelu, który obejmuje wszystkie możliwości adnotacji danych i umożliwia bardziej zaawansowaną konfigurację, która nie jest możliwa przy użyciu samych adnotacji danych. Adnotacje danych i płynny interfejs API mogą być używane razem.

Aby uzyskać dostęp do płynnego interfejsu API, zastąpisz metodę OnModelCreating w obiekcie DbContext. Załóżmy, że chcemy zmienić nazwę kolumny, w której przechowywane jest User.DisplayName, na display_name.

  • Zastąpij metodę OnModelCreating w obiekcie BloggingContext przy użyciu następującego kodu
public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
            .Property(u => u.DisplayName)
            .HasColumnName("display_name");
    }
}
  • Użyj polecenia Add-Migration ChangeDisplayName, aby wygenerować szkielet migracji, stosując te zmiany do bazy danych.
  • Uruchom polecenie Update-Database , aby zastosować nową migrację do bazy danych.

Nazwa kolumny DisplayName została teraz zmieniona na display_name:

Schemat o zmienionej nazwie wyświetlanej

Podsumowanie

W tym przewodniku przyjrzeliśmy się programowi Code First przy użyciu nowej bazy danych. Zdefiniowaliśmy model przy użyciu klas, a następnie użyliśmy tego modelu do utworzenia bazy danych i przechowywania i pobierania danych. Po utworzeniu bazy danych użyliśmy funkcji Code First Migrations w celu zmiany schematu w miarę ewolucji modelu. Pokazano również, jak skonfigurować model przy użyciu adnotacji danych i interfejsu API Fluent.