Allineamento di un DB
Entity framework si occupa autonomamente di gestire i passaggi necessari all'allineamente di un DB con le sue migrazioni; in caso quindi un database abbia già la firma (la tabella __efmigrationhistory è popolata) basterà utilizzare i comandi di migrazione di EF per eseguire l'allineamento.
Se il database non è firmato o se non è disponibile (nel caso di un nuovo cliente) invece sarà necessario prima eseguire qualche processo preliminare per poter aggiornare il modello in maniera automatica.
Questo viene considerato il primo passaggio perchè il resto delle operazioni suppone che il database collegato al modello abbia la firma di EF
Creare un databse con la struttura di Entity framework
Con EF
Sempre puntando ad un database vuoto (manager_settings.json) posso lanciare dotnet ef database update da Visual Studio per creare automaticamente la struttura del modello nel DB
Firmare un database con Entity Framework
Creare un database con la struttura di base
La pratica corretta per firmare un database è quella di allineare la sua struttura con la struttuna iniziale del modello Entity Framework, con struttura iniziale si intende il modello nella sua prima migrazione.
Abbiamo bisogno di avere questa struttura da qualche parte.
In caso non sia già disponibile è possibile creare uno schema velocemente con entity framework con:
dotnet ef database update initial
Calcolare le differenze con il database attuale
Verranno ora calcolate le differenze tra la struttura firma e la struttura del DB corrente, per ottenere ciò verrà utilizzato il tool "atlas.exe" che richiederà il database che vogliamo allineare e la struttura di quello già firmato da EF con la seguente sintassi:
from: Il database corrente, quello che vogliamo firmare ed aggiornare.
to: Il database a cui vogliamo allinearci (Solitamente la struttura ef appena creata).
.\utility\atlas.exe schema diff --from mysql://user:pass@host:port/db
--to mysql://user:pass@host:port/db > differences.sql
Viene riportato di sotto un esempio pratico:
C:\PROROB\utility>atlas.exe schema diff --from mysql://root:XXXX-XXXX-XXXX-XXXX@192.168.161.26:3306/pronet-iot_ef --to mysql://root:XXXX-XXXX-XXXX-XXXX@192.168.161.26:3306/pronet-iot_database-model > differences.sql
Al momento il file differences.sql ha qualche imperfezione e non può essere utilizzato.
-
Eliminare il controllo per utf8mb3 che potrebbe essere presente nella prima riga.
-
Disattivare il controllo delle chiavi esterne, aggiungendo questa riga all' inizio dello script.
SET FOREIGN_KEY_CHECKS=0; -
Disabilitare (e poi riattivare) gli update di timestamp automatico di alcune colonne per preservare il dato. Queste query andrebbero eseguite rispettivamente prima e dopo lo script generato con Atlas.
-- DECTIVATE
ALTER TABLE mes_workings
CHANGE wk_timestamp
wk_timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
ALTER TABLE mes_workorders
CHANGE wo_timestamp
wo_timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
ALTER TABLE scada_subworkings
CHANGE sk_timestamp
sk_timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
-- ACTIVATE ANGAIN BACK
ALTER TABLE mes_workings
CHANGE wk_timestamp
wk_timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
ALTER TABLE mes_workorders
CHANGE wo_timestamp
wo_timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
ALTER TABLE scada_subworkings
CHANGE sk_timestamp
sk_timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP -
Riparare eventuali dati mancanti e/o errati che vengono segnalati come errore, di seguito sono riportate query di fix per eventuali date mancanti in mes_workorder (problema spesso riscontrato)
-- DATE
UPDATE mes_workorders
SET wo_delivery_date = COALESCE(wo_delivery_date, wo_timestamp)
WHERE wo_delivery_date IS NULL;
UPDATE mes_workorders
SET wo_nominal_delivery_date = COALESCE(wo_nominal_delivery_date, wo_delivery_date)
WHERE wo_nominal_delivery_date IS NULL;
UPDATE mes_workorders
SET wo_nominal_scheduling_date = COALESCE(wo_nominal_scheduling_date, wo_scheduling_date)
WHERE wo_nominal_scheduling_date IS NULL;
File sql di template
Lanciare lo script di allineamento
Dopo aver eseguito le modifiche allo scritp è possibile applicare il file .sql al nostro df che dobbiamo allineare, per lo scopo verrà utilizzato:
C:\PROROB\bin_srv\mariadb\bin\mysql -h <host> -u <user> -p<password> <db> < <differences file>
-h <host> non sarà ovviamente necessario in caso facessimo questa operazione in locale.
Riempire la tabella delle migrazioni
Come ultima operazione avremo quella di copiare il contenuto della tabella __efmigrationhistory visto che non è presente un comando che lo faccia in automatico nelle differenze; possiamo utilizzare la seguente query per lo scopo
INSERT INTO `__efmigrationshistory`(`migration_id`, `product_version`) VALUES ('20231016094430_Initial','7.0.12')
Aggiornare il database
A questo il nostro database sarà allineato alla prima migrazione del nostro modello EF, sarà quindi necessario portarlo all'ultima migrazione. Possiamo usare pronet per questo se nella macchiana del cliente abbiamo una versione aggiornata.
ProNet.exe --migrate-database
Creazione script idempotenti
dotnet ef migrations script --idempotent
Lo script idempotente è l'insieme di istruzioni necessarie per allineare un certo DB, si può vedere un po' come quello che automaticamente viene eseguito normalmente quando viene lanciato dotnet ef database update.