Struttura delle classi B generate da BStudio
Separazione fra codice generato e codice manuale
La stessa classe è divisa in due file partial:
BClasses/BCliente.cs generato da BStudio, non modificare
BClassesPartial/BCliente.cs scritto dallo sviluppatore
La cartella BClasses viene creata da BStudio alla prima generazione. BStudio può rigenerare il primo file senza conoscere né sostituire il secondo.
Dichiarazione
Una classe generata segue normalmente questa forma:
public partial class BCliente : B.BBaseClass.BBaseObject, IEquatable<BCliente>
Il nome effettivo deriva dalla tabella mappata.
Chiave univoca
BUniqueKey è un record struct annidato che contiene la chiave primaria, anche quando questa è composta da più colonne. GetBUniqueKey() restituisce la chiave dell'istanza.
La chiave viene usata per:
uguaglianza e confronto;
ricerca veloce nei dictionary interni;
sincronizzazione delle collezioni figlie;
identificazione di inserimenti, modifiche ed eliminazioni.
Costruttori
La generazione può produrre:
costruttore vuoto;
costruttore con
IBConnection;costruttore con
DataRoweIBConnection;costruttore con i valori della chiave primaria e
IBConnection;ulteriori costruttori manuali nella parte
BClassesPartial.
Il costruttore con chiave carica l'oggetto usando lo stored procedure di selezione e parametri creati dalla connessione.
Proprietà delle colonne
Ogni colonna viene rappresentata con un tipo C# coerente. I campi nullable del database diventano tipi nullable quando necessario.
Esempi di convenzione:
intero:
int;decimale o valuta:
double;data o ora:
DateTime;campo nullable:
double?,DateTime?o altro tipo nullable coerente;testo:
string;booleano:
bool;contenuto binario:
byte[].
MappingData
MappingData(DataRow) assegna le colonne alle proprietà usando BConvert, quindi richiama PartialMappingData(DataRow).
La parte manuale può sovrascrivere PartialMappingData e deve normalmente terminare richiamando l'implementazione base.
Relazioni oggetto
Una chiave esterna può generare una proprietà oggetto caricata su richiesta. La proprietà:
conserva un campo privato;
usa la connessione dell'istanza;
ricarica l'oggetto quando cambia la chiave;
può essere marcata
[JsonIgnore]per evitare grafi ricorsivi nella serializzazione.
La chiave scalare e la proprietà oggetto hanno responsabilità differenti: non eliminare la proprietà chiave dal modello.
Collezioni figlie
Una relazione uno-a-molti può generare:
proprietà
List<T>?caricata al primo accesso;dictionary privato indicizzato tramite
T.BUniqueKey;metodo di caricamento;
metodo di salvataggio della collezione.
Durante il salvataggio vengono confrontati stato in memoria e stato nel database:
chiave presente e oggetto modificato:
UPDATE;chiave nuova:
INSERT;chiave rimasta soltanto nel database:
DELETE.
Le liste e i dictionary generati fanno parte del meccanismo di persistenza; non sostituirli con collezioni parallele.
Update
La firma tipica è:
bool Update(bool SaveCollections = true,
bool ForceInsert = false,
bool WithnewTransaction = true)
Comportamento:
verifica la connessione;
apre database e transazione quando richiesto;
pulisce e aggiunge i parametri;
richiama
PartialUpdate();decide fra inserimento e aggiornamento tramite
IsNothingoForceInsert;salva le collezioni quando richiesto;
esegue commit o rollback;
aggiorna lo stato dell'oggetto e richiama
UpdatePlus();chiude la gestione della transazione aperta dal metodo.
Quando l'operazione fa parte di una transazione esterna, impostare coerentemente WithnewTransaction senza creare transazioni annidate manuali.
Delete
Delete(bool WithnewTransaction = false) elimina l'istanza tramite lo stored procedure generato. Restituisce false se l'oggetto è IsNothing o manca la connessione.
Metodi statici
Le classi possono esporre metodi come GetElenco(IBConnection, params IDbDataParameter[]), che restituiscono un DataTable usando lo stored procedure di ricerca generato.
Uguaglianza
La classe implementa IEquatable<T>, Equals, GetHashCode e gli operatori ==/!=. Questo permette alla sincronizzazione delle collezioni di individuare gli oggetti modificati.
Eventi di log
Le classi possono esporre WriteLog per notificare origine, metodo, eccezione e gravità degli errori. Non sostituire automaticamente questo meccanismo con scritture locali non coordinate.
Hook di personalizzazione
Gli hook principali ereditati da BBaseObject comprendono:
PartialMappingData(DataRow);PartialUpdate();UpdatePlus().
La disponibilità effettiva va verificata nella versione di BBaseObject e nella classe generata. La parte manuale può inoltre aggiungere costruttori, proprietà calcolate, metodi e implementazioni di interfacce.
