Kilder:
https://docs.microsoft.com/en-us/ef/ef6/modeling/code-first/data-annotations
https://www.c-sharpcorner.com/article/dataannotations-in-depth/
I denne opgave tager vi udgangspunkt i eksemplet ItemsRazor ItemRazorV10.zip
I stedet for persistens via Json-filer skal data nu gemmes i en lokal Database ItemDb. Vi vil i denne opgave benytte Entity Framework Code First tilgangen, idet vi allerede har en kørende applikation med eksisterende Model-klasser. Vi vil autogenerere databasen og benytte Migration tool så databasen kan holdes i sync, hvis modellen senere bliver opdateret.
Step 1 (Models-class: Item.cs)
Når Databasens tabeller skal genereres ud fra model-klasserne, gøres det bl.a. på baggrund af DataAnnotations.
Bemærk:[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
Step 2 (Models-class: User.cs)
Step 3 (EF: NuGet Packages)
Da Entity Framework Core ikke er includeret i .Net Core (pr default) skal følgende pakker installeres i projektet (ItemRazorV1->Manage NuGet Packages):
Step 4 (EFDbContext/ItemDbContext)
Opret en ny mappe: EFDbContext og tilføj en class ItemDbContext.
ItemsDbContext skal extende class DbContext, override OnConfiguring( ) metoden og have følgende properties DbSet<Item> og DbSet<User>:
public class ItemDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlServer(@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=ItemDB; Integrated Security=True; Connect Timeout=30; Encrypt=False");
}public DbSet<Item> Items { get; set; }
public DbSet<User> Users { get; set; }
}
Bemærk: Et alternativ til at override OnConfiguring( ) er at oprette en "ConnectionStrings" i appSettings.json.
Step 5
(Program.cs)
Da "connectionString" er inkluderet via override af OnConfiguring( ), er det ikke nødvendigt at specificere den i configureringen af Context service i Program.cs filen.
Alt hvad der blot skal tilføjes, er en simpel registrering af service klassen:
builder.Services.AddDbContext<ItemDbContext>();
Bemærk: Hvis det ikke er opdateret i filen, så opdater CompabilityVersion.Version fra version 2_2 til 3_0: SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
Vi vil benytte Migration til at bygge vores Database på baggrund af domain klasserne (Model-klasser)
Step 6 (PMC)
Vi benytter Visual Studio og Package Manager Console Tools til migreringen. Åben PMC med:
Tools -> NuGet Package Manager -> Package Manager Console
Step 7 (DbService Get)
Opret en ny klasse DbService i mappen Services.
Klassen skal have metoder der kan hente Items og Users, dvs der skal være metoder ala:
public async Task<List<Item>> GetItems()
{
using (var context = new ItemDbContext())
{
return await context.Items.ToListAsync();
}
}
Bemærk:
Metoderne skal kunne afvikles asynkront, hvorfor de skal være af typen async og returnere et Task-objekt. Der benyttes await da der ikke skal returneres noget før listen er klar.
Items i ItemDbContext er af typen DbSet, hvorfor der konverteres til typen List (og det gøres her async). Bemærk også brugen af using( ...){...} den opretter de nødvendige resourcer og frigiver dem automatisk efter brug.
Step 7 (DbService Add og Save)
Tilføj metoder der kan tilføje nye Items og Users til DbSet i context ala:
public async Task AddItem(Item item)
{
using (var context = new ItemDbContext())
{
context.Items.Add(item);
context.SaveChanges();
}
}
Samt metoder til at kunne gemme Items og Users i databasen ala:
public async Task SaveItems(List<Item> items)
{
using (var context = new ItemDbContext())
{
foreach (Item item in items)
{
context.Items.Add(item);
context.SaveChanges();
}context.SaveChanges();
}
}
public async Task SaveUsers(List<User> users)
{
using (var context = new ItemDbContext())
{
foreach (User user in users)
{
context.Users.Add(user);
}
context.SaveChanges();
}
}
Husk: at kalde SaveChanges efter item/user de er tilføjet, ellers opdateres databasen ikke.
Step 8 (Program.cs)
Registrer den nye service DbService i Program.cs, så den kan benyttes af ItemService og UserService.
Step 9 (UserService og ItemService)
Tilføj referencer til DbService og injicer servicen i konstruktørerne.
Opdater konstruktørerne så klasserne benytter Databasen istedet for Json-filerne.
Bemærk: Der kan "leges" lidt med at indlæse fra json og gemmes i Db første gang (så kan data nemt genbruges)
Ps. Husk Result når Items og Users skal
hentes via DbService ala. _users = _dbService.GetUsers().Result;
Step 10 (Afprøv)
Afprøv at applikationen virker.
Step 11 (Generisk DbService)
Gør DbService generisk (ala JsonFileService) - så der ikke er så meget "copy-paste" kode!
God fornøjelse!
Henrik Høltzer