Posts
83
Comments
165
Trackbacks
11
[LINQ2SQL] Modalità di caricamento

Nell'ottica di sfruttare al meglio le potenzialità di un ORM in genere, e di LINQ2SQL in particolare (anche se a mio modesto parere è un "ibrido") bisogna, come da molte parti è già stato suggerito, "ricordarsi di non dimenticare" che sempre con un database relazionale abbiamo a che fare.
Questo preambolo per dire che il miglior suggerimento che si può dare a chi inizia ad utilizzare Linq2Sql è quello di non dimenticarsi MAI di abbinare l'utilizzo di un profiler per vedere cosa stiamo cercando di far fare al nostro db...

In un semplice esempio (il database di riferimento è il "famoso" AdventureWorks) possiamo notare come l'utilizzo fuori controllo di designer e strumenti RAD possono "deviare" dal corretto/miglior utilizzo delle tecnologie che abbiamo a disposizione:

 

Di default il caricamento definito nel DataContext è un "caricamento tardivo", quindi nell'esempio di codice seguente il caricamento degli indirizzi che soddisfano il criterio impostato viene scatenato nel momento in cui inizia l'iterazione sul risultato, all'interno del ciclo foreach.
La selezione del nome dello stato (o della provincia) associata all'indirizzo corrente scatena, ad ogni ciclo nuovi round-trip sul database, se l'oggetto StateProvince non è ancora stato caricato (non presente nel DataContext).

E il risultato del profiler è impietoso...

Questo semplice caso è lampante e mette in evidenza come, senza conoscere la modalità con cui Linq2Sql "mappa" le nostre query, rischiamo veramente di mettere sotto-stress il database, facendolo lavorare nel modo a lui meno congeniale.

Per un corretto caricamento (in questo caso), bisogna istruire il DataContext affinchè i round-trip sul database siano limitati e quindi le n-select precedenti siano effettivamente un'unica richiesta sulle tabelle degli indirizzi e degli stati legate tramite una join.

Così facendo il risultato la query creata da Linq2Sql, diciamo così, mi piace di più:

exec sp_executesql N'SELECT
[t0].[AddressID],
...
[t1].[StateProvinceID]
...
FROM [Person].[Address] AS [t0] INNER JOIN [Person].[StateProvince] AS [t1] ON [t1].[StateProvinceID] = [t0].[StateProvinceID]
WHERE [t0].[City] LIKE @p0',N'@p0 nvarchar(2)',@p0=N'A%'

posted on lunedì 28 gennaio 2008 11:34 Print