ABONAMENTE VIDEO REDACȚIA
RO
EN
×
▼ LISTĂ EDIȚII ▼
Numărul 102
Abonament PDF

Entity Framework: Exemplu despre cum să schimbi modul de lucru „Database First” cu „Code First"

Mariana Lazurean
.NET Developer @ Siemens
PROGRAMARE


În calitate de programator, poți lucra la o aplicație complet inovatoare sau la o aplicație nouă, bazată pe o altă aplicație existentă. O aplicație complet nouă este o situație fericită pentru că aduce cu ea o arhitectură nouă și ultimele tehnologii. Pe scurt, aceasta oferă avantajele oricărui start de la zero. Spre deosebire de aceasta, aplicația nouă, bazată pe o altă aplicație existentă, aduce cu ea riscurile unei baze de date deja configurate.

Toți vrem să lucrăm la o aplicație complet nouă, dar cei mai mulți dintre noi lucrează la o aplicație nouă, bazată pe o altă aplicație existentă. Pentru că aplicația existentă este folosită, utilizatorii acestei aplicații își doresc să folosească aplicația nouă cât mai repede.

Cum ar trebui integrată baza de date existentă în aplicația nouă?

Care este cel mai bun mod de lucru pentru a avea o dezvoltare rapidă a noii aplicații? Pentru acest exemplu, baza de date folosită este MS SQL și Entity Framework este sistemul ORM.

Despre migrările "Code First"

Într-o aplicație, modelele de date se adaugă și se schimbă frecvent, ajungând să nu mai fie sincronizate cu baza de date. Cu metoda de lucru "Code First" migrările sunt folosite pentru a păstra sincronizate modelele de date cu baza de date.

Migrările permit crearea unei baze de date inițiale care lucrează cu Entity Framework. Pentru fiecare set de schimbări, o nouă migrare trebuie generată ca să sincronizeze baza de date.

Metoda "Code First" permite să se sincronizeze schema bazei de date în loc să se șteargă și să se recreeze baza de date.

Despre metoda "Database First"

Baza de date există și poate fi folosită.Metoda "Database First" este o alternativă a metodei "Code First", în care se creează clasele POCO din baza de date existentă.

În orice aplicație, în timpul dezvoltării, apar noi cerințe care necesită schimbări în baza de date. Baza de date este modificată manual și modelele de date sunt sincronizate în acord cu modificările din baza de date.

Modelele de date se creează pornind de la tabelele din baza de date relațională (comanda scaffold din Package Manager Console).

Care metodă este mai potrivită pentru a avea o implementare rapidă?

O comparație între metodele "Code First" și "Database First" ne va ajuta să luăm o decizie.

Code First Database First
New Models Write them manually in .Net. Migrate to Scaffold them from database.
database.
Change Models Change in .Net. Migrate to database. Change in database. Scaffold from
database.
Remove Models Remove in .Net. Migrate to database. Remove in database. Remove in .Net.
History of Models Changes Yes No
Developers use the same database Migrations resolve the changes. Developers have the changes.
Developers use a local database Migrations resolve the changes. Every developer should apply the changes
locally.

"Database First" poate fi folosită să se obțină modelele de date din baza de date. Când avem modelele de date, "Code First" este recomandată să fie folosită pentru schimbările care apar.

Așadar, în cazul nostru, soluția de mijloc este cea mai bună. Vom folosi ambele metode, "Database First" la început, doar ca să obținem modelele din baza de date și, după aceea, vom continua cu metoda "Code First" pentru schimbările care apar ulterior.

Cum să schimbi modul de lucru "Database First" cu "Code First"?

Nu uita că baza de date există și o nouă aplicație este în dezvoltare.

Ca să nu fie afectată această aplicație, un proiect nou este creat temporar doar ca să obținem modelele de date din baza de date. Folosind metoda "Database First", modelele de date sunt obținute din baza de date.

După ce avem modelele, verificăm dacă acestea generează o bază de date identică. Pentru aceasta vom schimba stringul de conectare la o bază de date nouă.

Acum putem schimba metoda de lucru și să folosim în continuare "Code First" pentru crearea migrării inițiale pentru o nouă bază de date specificată în stringul de conectare. Această migrare inițială s-ar putea să nu conțină toate informațiile pentru a se putea crea noua bază de date. Din acest motiv, s-ar putea să se afișeze erori când se aplică prima migrare și noua bază de date să nu se creeze. Aceste erori trebuie rezolvate schimbând manual prima migrare.

Structura bazei de date vechi și structura bazei de date noi se pot compara, doar ca să ne asigurăm că am obținut ceea ce doream. Dacă totul este așa cum ne-am așteptat, atunci tabela __EFMigrationHistory din noua bază de date trebuie importată în vechea bază de date, ca să putem folosi în continuare, în aplicație, metoda "Code First" pentru schimbările care vor apărea.

Pe urmă, mutăm și modelele de date din proiectul temporar în aplicație unde la dezvoltare s-a folosit metoda "Database First" și continuăm dezvoltarea aplicației folosind metoda "Code First".Un exemplu al modului cum se face această schimbare de la o metodă la alta este descris mai jos.

Pasul 1: Creăm un proiect .Net Web API

Creăm un proiect nou .Net Web API și instalăm pachetele următoare din NuGet pentru a putea obține modelele și DBContext din baza de date:

Generăm modelele de date folosind metoda "Database First", rulând următoarea comandă în Package Manager Console:

Scaffold-DbContext
 -Provider Microsoft.EntityFrameworkCore.SqlServer
 -Connection "Data Source=...;

Integrated Security = True; Initial Catalog = ...;"

Modelele sunt generate și apar în proiect.

Pasul 2: Setăm proiectul Web API pentru First Migration

Setăm stringul de conectare la o bază de date nouă, NU la baza de date existentă.

Modelele generate și contextul bazei de date pot fi mutate in directorul "Models" al proiectului. De asemenea, Startup.cs și Program.cs trebuie să fie actualizate pentru DBContext generat.

Cu metoda "Code First", migrarea inițială numită InitialCreate trebuie creată din Package Manager Console folosind comanda Add-Migration InitialCreate.

Ca să sincronizăm baza de date trebuie doar să pornim aplicația .Net sau să rulăm comanda Update-database -Verbose din Package Manager Console.

În funcție de informațiile și setările din baza de date existentă, s-ar putea să se afișeze ceva erori la sincronizare. În pasul următor, trebuie sa rezolvăm toate aceste erori.

Pasul 3: Rezolvarea erorilor

Erorile apar când proiectul .Net pornește sau când rulăm comanda update-database -Verbose din Package Manager Console.

Exemplu de astfel de erori care pot să apară este că unele câmpuri din SQL folosesc o funcție definită în SQL, și această funcție nu există în baza de date nouă care trebuie creată. Ca să rezolvăm această eroare, funcția SQL care lipsește, trebuie să o adăugăm manual în migrarea inițială.

Un alt exemplu de eroare este că, dacă sunt definiți utilizatori și roluri în SQL, fără drepturile necesare, unele tabele nu se pot crea. Ca să rezolvăm această eroare, utilizatorii și rolurile trebuie adăugate manual în migrarea inițială.

După ce s-au rezolvat toate erorile și noua bază de date a fost generată, putem trece la pasul următor.

Pasul 4: Comparăm baza de date existentă cu baza de date nou creată

Ca să fim siguri că modelele obținute din baza de date existentă generează o bază de date similară, folosind migrarea InitialCreate, trebuie să comparăm structura celor două baze de date.

Pentru că în exemplu s-a folosit bază de date MS SQL, din SQL Server Management Studio, generăm scripturi cu toate informațiile din baza de date nouă. Aceleași scripturi le generăm și din baza de date existentă.

Eu am folosit Total Commander/Compare by content, dar orice comparator text poate fi folosit pentru compararea acestor scripturi. Acum am comparat doar structura bazelor de date nu și datele din bazele de date.

Observație: Unele diferențe la unii indecși sunt acceptate, dar tabelele, cheile primare și cheile străine trebuie să fie la fel.

Oricum vom folosi baza de date existentă și acolo vom avea toate informațiile.

Pasul 5: Importăm tabela __EFMigrationsHistory

Până acum, cele două baze de date par să fie la fel.

Tabela __EFMigrationsHistory cu migrarea InitialCreate din baza de date nouă trebuie să o importăm în baza de date existentă. Pentru acest exemplu, SQL Server Management Studio a fost folosit și la importarea tabelei.

Pasul 6: Schimbă stringul de conectare

Pentru că vom folosi baza de date existentă de acum înainte, stringul de conectare trebuie să aibă valoarea potrivită.

Daca rulăm aplicația, atunci nici o schimbare nu se va face în baza de date existentă. De asemenea, dacă nu schimbăm nici un model și adăugăm o migrare nouă, această migrare va fi goală. Baza de date este sincronizată cu modelele de date.

Pasul 7: Fii atent

Când, de exemplu, se modifică un model, se șterge o proprietate, în migrare trebuie incluse modificările manuale din views, store procedures, functions, triggers etc.

Concluzii

Vechea bază de date nu a fost modificată pe parcursul acestui exemplu. Modelul "Code First" poate fi folosit în proiect pentru viitoarele modificări ale modelelor după migrarea inițială.

Acești pași pot fi făcuți chiar dacă implementarea noii aplicații este începută și programatorii au lucrat cu modelul "Database First" până acum. Modelele de date, migrarea InitialCreate pot fi copiate în noua aplicație și se poate continua implementarea folosind modelul "Code First".

Pentru alte sisteme ORM care suportă "Code First" și "Database First", aceeași strategie poate fi folosită pentru a schimba modelul de lucru "Database First" cu "Code First".

Sunt și alte exemple cum să folosești "Code First Migrations" cu o bază de date existentă.

Referințe

  1. Code First to an Existing Database - EF6 | Microsoft Docs

Studiu: Reacția companiilor IT
la criza Covid-19

Prezentare studiu și
panel de discuții

Luni, 12 Aprilie, ora 17:00

Înregistrează-te

Facebook Meetup StreamEvent YouTube

Conferință

VIDEO: NUMĂRULUI 105

Sponsori

  • Accenture
  • Bosch
  • ntt data
  • Betfair
  • FlowTraders
  • MHP
  • Connatix
  • Cognizant Softvision
  • BoatyardX
  • Colors in projects