LINQ to Sql e Guid autogenerati

Durante la realizzazione del layer di accesso ai dati di una semplice demo app, per il quale avevo scelto di utilizzare LINQ to Sql, sono incorso in un noioso bug nel recupero dei valori delle PrimaryKey, nel caso in cui questi siano autogenerati dal server di database.

Supponiamo di avere una tabella del tipo seguente, in cui la PK sia di tipo uniqueidentifier, automaticamente inizializzata per le nuove righe tramite la funzione di sistema newid():

image

Creiamo un nuovo DataContext di LINQ to Sql e importiamo al tabella creata; il designer crea una nuova entity con i campi omonimo delle colonne sul database:

image

Spesso, lato schema DB, i nomi delle chiavi contengono un riferimento alla tabella a cui appartengono. Per quanto riguarda le entità di dominio, invece, preferisco che gli identificativi si chiamino tutti allo stesso modo, sia per una questione di uniformità e leggibilità (non essendoci FK ma semplici riferimenti, non ho più la necessità di avere nomi diversi), sia perchè, ad esempio, potrei pensare di far implementare a tutte le mie entity un'interfaccia IHasIdentifier che esponga la proprietà Id e utilizzarla per implementare un GetById generico. Quindi, forte delle mie convinzioni, procedo alla modifica sulla entità di L2S generata dal designer:

image

Inoltre, mi ricordo anche di impostare, sulla property grid, che la proprietà Id è auto generata da DB e che deve essere recuperata dopo una query di Insert:

image

In fase di fetch, LINQ to Sql svolge egregiamente il suo lavoro, trasformando correttamente ogni condizione sulla proprietà Id in una where sulla colonna MySampleId:

image

image

Ciò purtroppo non accade quando, dopo una query di Insert, L2S tenta di recuperare il valore della chiave generata da database. Come si nota dalla query, infatti, viene erroneamente cercata una colonna chiamata Id, con successivo ed ovvio errore di Sql Server.

image

Ho segnalato il problema nei forum di MSDN, e mi è stato risposto che si tratta di un bug che verrà corretto con il rilascio del SP1. Attualmente ci sono solo due soluzioni:

  1. Utilizzare i medesimi nomi per proprietà e colonne
  2. Inizializzare manualmente la proprietà ad un nuovo Id sul costruttore della entity

Un'ultima curiosità: tutto ciò non si verifica nel caso in cui la PK sia un Identity e il motivo è che, in quel caso, Linq to Sql utilizza SELECT SCOPE_IDENTITY per recuperare il nuovo valore.

Technorati Tags:
5 Comments Filed Under [ .Net 3.5 ]

Comments

# re: LINQ to Sql e Guid autogenerati
Gravatar Questo, almeno per il momento, lo rende inutilizzabile nei miei scenari, anch'io uso una property generica come Id.
Left by Tommaso Caldarola on 06/05/2008 14.29
# re: LINQ to Sql e Guid autogenerati
Gravatar Un appunto sull'utilizzo della funzione newid() per generare il guid. Se possibile (SQL2005 o maggiore) utilizzate newsequentialid(), come spiegato qui: http://msdn.microsoft.com/it-it/library/cc185044.aspx#ID0EEC
Left by Davide Mauri on 06/05/2008 14.35
# re: LINQ to Sql e Guid autogenerati
Gravatar Ottimo tip, grazie Davide!
Left by Marco De Sanctis on 06/05/2008 14.44
# re: LINQ to Sql e Guid autogenerati
Gravatar Grazie per il post, molto interessante, e specialmente utile!
Left by Nicolò Carandini on 07/05/2008 7.03
# re: LINQ to Sql e Guid autogenerati
Gravatar Interessante, purtroppo questo dimostra come Linq2Sql sia ancora per ora una libreria decisamente giovane, almeno rispetto a NHibernate.

Alk.
Left by Gian Maria on 09/05/2008 17.16

Leave Your Comment

Title*
Name*
Email (never displayed)
 (will show your gravatar)
Url
Comment*

Please add 7 and 1 and type the answer here:

Preview Your Comment.