Alcune volte, durante il nostro lavoro, ci capitano delle situazioni in cui siamo costretti a variare in maniera forzata il comportamento di default del nostro applicativo.
Così può capitare che lavorando con LINQ to SQL, vi siano delle situazioni in cui bisogna impostare delle particolari condizioni per definire un comportamento diverso da quello di default.
Visto che parliamo di LINQ to SQL, ricordiamo un attimo come funziona la creazione di un DataContext di questo tipo in Visual Studio. Normalmente i passaggi sono:
- aggiungere al nostro progetto (tramite File > Add > New Item > Data > LINQ to SQL Classes) un nuovo DataContext LINQ to SQL, che verrà creato in forma di tre files (.dbml, .dbml.layout e .designer.cs) pronti ad ospitare le nostre entity;
- tramite la finestra di Server Explorer andiamo a connetterci alla nostra istanza di Sql Server. A questo punto scegliamo la connessione e il database da utilizzare, selezioniamo le tabelle e/o viste e/o stored procedure che vogliamo gestire con il DataContext ed infine le trasciniamo con il drag&drop sul DBML vuoto;
Nel nostro esempio utilizzeremo un banale database con solo due tabelle molto semplici (Product e ProductCategory) per cui il risultato nel nostro file DBML sarà il seguente:
Come detto, all'interno della solution verranno creati tre file, uno con estensione .dbml, uno con estensione .dbml.layout e infine uno con .designer.cs o .designer.vb (a seconda che usiamo rispettivamente C# o Visual Basic).
Nel primo file vedremo la rappresentazione grafica che abbiamo appena riportato sopra, nel secondo la definizione xml della grafica rappresentata nel primo, e nel terzo le "entity" generate in automatico e che rappresentano il nostro modello a oggetti. In realtà la parte che noi vediamo come un contenitore grafico, ovvero il file .dbml contiene di fatto la parte di mapping di LINQ to SQL, mentre come dicevamo poco fa, la parte di code viene ospitata dal file .designer.cs. Sono queste due infatti, le componenti con cui principalmente viene creato questo strato di relazione tra le tabelle del database e le classi che utilizzeremo in loro vece (se vogliamo capire un pò meglio di cosa si tratta, basta aprire con un editor di testo il file .dbml vedremo che in pratica è un file xml che identifica appunto il mapping tra le tabelle e le entity).
Tornando alla nostra problematica, supponiamo di avere l'esigenza di settare qualche impostazione in modo da far comportare le classi del DataContext in maniera diversa rispetto al loro "standard". Supponiamo di avere la necessità che il campo LastUpdate, presente in entrambi le tabelle, venga escluso dalla verifica della concorrenza, per evitare problemi quando viene effettuato il commit fisico sul database.
Per fare ciò basta aprire il file DBML, selezionare una alla volta queste proprietà delle entity, e nella finestra delle proprietà impostarne il valore di "Update Check" su "Never". In questo modo indichiamo che le proprietà sono soggette ad una policy di tipo "last-update-wins".
Nel nostro banale esempio abbiamo solo due tabelle, ma nei casi reali potremmo tranquillamente avere decine se non centinaia di tabelle su cui applicare questa modifica. Inoltre, qualora cambiasse qualcosa sul database e dovessimo rigenerare l'intero DataModel, dovremmo rieffettuare tutte le modifiche.
Si capisce quindi che questa non è la strada giusta, per cui dobbiamo trovare un altro sistema per farlo. Una prima soluzione consiste nel configurare i campi nel momento in cui istanziamo il DataContext. Sfortunatamente, nel momento in cui istanziamo il DataContext, questa impostazione è già stata utilizzata e modificarla a runtime non sortirebbe alcun effetto. Questo comporta che la modifica va effettuata prima dell'istanziazione del DataContext.
Una possibile soluzione, che è poi l'argomento in questione, sta nel creare il DataModel in maniera diversa, ovvero utilizzando SqlMetal.
Introduzione a SqlMetal
SqlMetal è un applicativo da linea di comando che fa parte del Microsoft Windows Software Development Kit, installato insieme a Visual Studio oppure liberamente scaricabile all'indirizzo http://msdn.microsoft.com/en-us/windows/bb980924.aspx.
SqlMetal è in grado di produrre il file .dbml, il file .dbml.layout e le classi nel file .designer.cs|vb così come avviene utilizzando Visual Studio. Ma a che scopo dobbiamo usare uno strumento esterno per fare le stesse cose che possiamo fare con Visual Studio? Quale è il vantaggio pratico nel farlo?
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Utilizzare i primary constructor di C# per inizializzare le proprietà
Come EF 8 ha ottimizzato le query che usano il metodo Contains
Utilizzare Model as a Service su Microsoft Azure
Utilizzare il metodo CountBy di LINQ per semplificare raggruppamenti e i conteggi
Miglioramenti nell'accessibilità con Angular CDK
Esportare ed analizzare le issue di GitHub con la CLI e GraphQL
Ottimizzare il mapping di liste di tipi semplici con Entity Framework Core
Usare lo spread operator con i collection initializer in C#
Supporto ai tipi DateOnly e TimeOnly in Entity Framework Core
Escludere alcuni file da GitHub Secret Scanning
Configurare il nome della run di un workflow di GitHub in base al contesto di esecuzione