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 ukierunkowanie bazy danych, która nie istnieje, a program Code First utworzy lub pustą bazę danych, do którego zostanie dodana nowa tabela Code First. 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
Ten film wideo zawiera wprowadzenie do programowania Code First przeznaczonego dla nowej bazy danych. Ten scenariusz obejmuje ukierunkowanie bazy danych, która nie istnieje, a program Code First utworzy lub pustą bazę danych, do którego zostanie dodana nowa tabela Code First. 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.
Prezenter: Rowan Miller
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 pliku 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 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 z elementu System.Data.Entity.DbContext i uwidacznia typizowane wartości TEntity> 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 instrukcję using dla elementu System.Data.Entity w górnej części pliku Program.cs.
using System.Data.Entity;
Poniżej klasy Post w pliku 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ć pliki 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óry musimy rozpocząć przechowywanie i pobieranie danych. 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 pliku 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ą DbContext utworzył bazę danych.
- 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 Połączenie ion (Jak narzędzie DbContext odnajduje model i bazę danych Połączenie ion). 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łączenie ions danych i wybierz pozycję Dodaj Połączenie ion...
Jeśli nie nawiązaliśmy połączenia z bazą danych z Eksploratora serwera przed wybraniem programu Microsoft SQL Server jako źródła danych
Połączenie do lokalnej bazy danych lub programu SQL Express, w zależności od zainstalowanego
Teraz możemy sprawdzić schemat utworzony przez program Code First.
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 lub 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 włączenie Migracje Code First dla naszego pliku BloggingContext.
Narzędzia —> Menedżer pakietów biblioteki —> konsola Menedżer 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 używane przez migracje do migrowania pliku 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, reprezentuje zmiany, które zostały już zastosowane do bazy danych, aby pobrać ją z pustej bazy danych do tej, która zawiera tabele Blogi i Wpisy. Mimo że firma Code First automatycznie tworzy te tabele, teraz, gdy wyraziliśmy zgodę na migracje, które zostały przekonwertowane na 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 zamawiania.
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 AddUrl addu migration w konsoli Menedżer pakietów. Polecenie Add-Migration sprawdza zmiany od ostatniej migracji i szkieletów nowej migracji z wszelkimi znalezionymi zmianami. Możemy nadać nazwę migracji; w tym przypadku wywołujemy migrację "AddUrl". Kod szkieletowy mówi, że musimy dodać kolumnę Url, która może przechowywać dane ciągu, do bazy danych. Tabela blogów. 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żer pakietów. To polecenie spowoduje zastosowanie 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: Możesz użyć przełącznika –Verbose podczas wywoływania bazy danych Update-Database, aby zobaczyć sql, który jest wykonywany względem bazy danych.
Nowa kolumna Url jest teraz dodawana do tabeli Blogs w bazie danych:
6. Adnotacje danych
Do tej pory po prostu pozwoliliśmy ef odnajdywać model przy użyciu jego domyślnych konwencji, ale będą czasy, kiedy nasze klasy nie przestrzegają konwencji i musimy mieć możliwość wykonania dalszej konfiguracji. 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ć zestaw do naszego kontekstu pochodnego
public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
public DbSet<User> Users { get; set; }
}
- Jeśli podjęto próbę dodania migracji, zostanie wyświetlony błąd z informacją" EntityType "Użytkownik" nie ma zdefiniowanego klucza. Zdefiniuj klucz dla tego typu jednostki". ponieważ program EF nie ma możliwości znajomości, że nazwa użytkownika powinna być kluczem podstawowym dla użytkownika.
- Teraz użyjemy adnotacji danych, więc musimy dodać instrukcję using w górnej części pliku 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 utworzyć szkielet migracji, aby 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:
Pełna lista adnotacji obsługiwanych przez program EF to:
- KeyAttribute
- StringLengthAttribute
- Maxlengthattribute
- ConcurrencyCheckAttribute
- Requiredattribute
- TimestampAttribute
- ComplexTypeAttribute
- Columnattribute
- Tableattribute
- InversePropertyAttribute
- ForeignKeyAttribute
- DatabaseGeneratedAttribute
- NotMappedAttribute
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. Płynny interfejs API to bardziej zaawansowany sposób określania konfiguracji modelu, który obejmuje wszystkie adnotacje danych, które mogą wykonywać oprócz bardziej zaawansowanej konfiguracji, która nie jest możliwa w przypadku 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órą jest przechowywany element User.DisplayName, aby 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 utworzyć szkielet migracji, aby zastosować 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:
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 Migracje Code First zmiany schematu w miarę ewolucji modelu. Pokazano również, jak skonfigurować model przy użyciu adnotacji danych i interfejsu API Fluent.