Crad's .NET Blog

L'UGIblog di Marco De Sanctis
posts - 190, comments - 457, trackbacks - 70

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:

Print | posted on Tuesday, May 6, 2008 1:09 PM | Filed Under [ .Net 3.5 ]

Powered by:
Powered By Subtext Powered By ASP.NET