Wprowadzenie

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: NuGet Package Manager

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: EFCore: add-migration

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: EFCore: update-database

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.