W tym wpisie utworzymy aplikację konsolową wykorzystując EF Core oraz podejście code-first. Aplikacja zostanie utworzona w oparciu o .NET Core 3.1 oraz Visual Studio 2019.
Po utworzeniu aplikacji musimy zainstalować wymagane paczki, które pozwolą nam na efektywną pracę z frameworkiem. Jeżeli nie pamiętacie ich nazw odsyłam do jednego z poprzednich wpisów: EF Core - instalacja
Model
Pierwszym krokiem jest utworzenie modelu, który będzie wykorzystywany do komunikacji z bazą danych. Model będzie reprezentował tabelę bazy danych a jego kształt (definicję) określimy wykorzystując atrybuty Data Annotations oraz Fluent API.
Utworzony model będzie wykorzystywany przez EF do operacji CRUD (create, read, update, delete).
Pierwszy krok w naszej aplikacji to utworzenie klasy encji oraz klasy kontekstowej, która wykorzysta defincję przygotowanych modeli. Poniżej najprostszy przykład dwóch modeli:
public class CarCompanies
{
public int Id { get; set; }
public string Brand { get; set; }
}
public class CarComapniesData
{
public int Id { get; set; }
public int CarCompanyId { get; set; }
public int Sale { get; set; }
}
Drugim krokiem jest utworzenie klasy kontekstowej o której pisałem w poprzednim wpiscie: EF Core - DbContext
W moim przypadku klasa kontekstowa przyjmuje poniższą postać:
public class ApplicationDbContext : DbContext
{
public DbSet<CarCompanies> CarCompanies { get; set; }
public DbSet<CarComapniesData> CarCompaniesData { get; set; }
public ApplicationDbContext()
{
}
// W naszej prostej aplikacji konsolowej będziemy się trzymać konwencji
// ze zdefiniowaniem connection-string w metodzie OnConfiguring
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(@"Server=PAWEL;database=EFCoreCodeFirst;Integrated Security=true");
}
}
}
Powyższa klasa kontekstowa zawiera dwie właściwości DbSet<TEntity> dla typów CarCompanies oraz CarCompaniesData. W metodzie OnConfiguring() wykorzystujemy DbContextOptionBuilder do określenia połączenia z bazą danych i jej typu. Podobnie jak w poprzednich przypadkach jest to Microsoft SQL Server - tym razem lokalna instancja.
Connection String omawiałem szczegółowo w poprzednim artykule. Tym razem dodam jedynie, że EF wykorzysta zawarte informacje w celu utworzenia bazy danych o wskazanej nazwie i lokalizacji podczas wykonywania migracji.
Po wykonaniu dwóch powyższych kroków nadszedł czas na dodanie migracji oraz utworzenie bazy danych na podstawie przygotowanej definicji.
Migracja
EF Core udostępnia różne polecenia:
Add-Migration
Drop-Database
Get-DbContext
Get-Migration
Remove-Migration
Scaffold-DbContext
Script-Migration
Update-Database
W naszym przypadku nie istnieje żadna baza danych. Musimy zatem dokonać utworzenia bazy danych na bazie modelu poprzez dodanie migracji.
Wszelkie polecenia będziemy wykonywać wykorzystując NuGet Package Manager Console dostępny z poziomu Visual Studio.
Konsolę otwieramy przechodząc przez menu narzędzi:
W celu dodania migracji korzystamy z poniższego polecenia:
PM> add-migration CreateCarsDB
Wykonanie powyższego polecenia skutkuje utworzeniem nowego folderu o nazwie Migrations jak na poniższym zrzucie ekranu:
Sam proces migracji opiszę szczegółowo w jednym z kolejnych wpisów. Na ten moment nie musimy wiedzieć więcej.
Po dodaniu migracji musimy jeszcze dokonać utworzenia bazy danych przy pomocy polecenia update-database:
PM> update-database
Wywołanie polecenia spowoduje utworzenie bazy danych o nazwie i lokalizacji określonej w connection string’u użytym w metodzie UseSqlServer(). Baza danych będzie składała się z dwóch tabel:
Pierwsza migracja jest już za nami. Każde kolejne dodanie/aktualizacja modelu/modeli wymaga synchronizacji z bazą danych poprzez ponowne wykonanie powyższych poleceń: add-migration oraz update-database.
W powyższym przypadku użyliśmy domyślnej definicji modelu. Na użycie Data Annotations oraz Fluent API przyjdzie jeszcze czas.
Podsumowanie
Zanim przejdziemy do kolejnego wpisu dodamy (w ramach testu i sprawdzenia czy proces migracji i tworzenia bazy danych przebiegł pomyślnie) przykładowe dane do bazy danych. W tym celu wykorzystamy dwa polecenia: Add oraz AddRange:
static void Main(string[] args)
{
using (var context = new ApplicationDbContext())
{
List<CarCompanies> carCompanies = new List<CarCompanies>()
{
new CarCompanies()
{
Brand = "Audi",
},
new CarCompanies()
{
Brand = "Maserati"
}
};
// Dodajemy zbiór danych
context.CarCompanies.AddRange(carCompanies);
context.SaveChanges();
// Dodajemy podstawowe inforamcje o sprzedaży
context.CarCompaniesData.Add(new CarComapniesData() { CarCompanyId = context.CarCompanies.SingleOrDefault(a => a.Brand == "Audi").Id, Sale = 45 });
context.CarCompaniesData.Add(new CarComapniesData() { CarCompanyId = context.CarCompanies.SingleOrDefault(a => a.Brand == "Maserati").Id, Sale = 4 });
context.SaveChanges();
}
}
W kolejnym wpisie zajmiemy się szczegółowym omówieniem procesu dodawania, aktualizacji oraz usuwania danych wykorzystując EF Core.