2010-01-27 7 views
5

Una delle cose che hai battuto in te come sviluppatore junior è che non esegui mai e poi mai un "SELECT *" su un set di dati, poiché è inaffidabile per diversi motivi.Linq no-noes - l'opzione catch all sql-like?

Da quando mi sono spostato su Linq (prima da Linq a SQL e poi Entity Framework), mi sono chiesto se l'equivalente di Linq è ugualmente disapprovato?

Eg

var MyResult = from t in DataContext.MyEntity 
       where t.Country == 7 
       select t; 

dovremmo selezionando in un tipo anonimo con solo i campi che vogliamo esplicitamente menzionati, o è la cattura tutto selezionare ora accettabile per LinqToSql et al causa del materiale extra che circonda i dati che fornire?

saluti

Moo

+2

Le persone che dicono che dovresti * mai *, * mai * fare $ x sono altrettanto prive di senso di quelle che ** sempre ** fanno $ x. –

+0

Oh, sono assolutamente d'accordo, ma * è * una delle regole d'oro ... – Moo

risposta

5

Non è malvisto, è determinato dal tuo caso d'uso. Se si desidera aggiornare il risultato e persistere, è necessario selezionare t, tuttavia se non si desidera farlo e sono solo query per scopi di visualizzazione, è possibile renderlo più efficiente selezionando le proprietà desiderate:

var MyResult = from t in DataContext.MyEntity 
       where t.Country == 7 
       select new { t.Prop1, t.Prop2 }; 

Questo è per alcuni motivi. La popolazione di un tipo anonimo è leggermente più veloce, ma ancora più importante è disables change tracking ... perché non è possibile mantenere un tipo anonimo, non è necessario tenere traccia delle modifiche.

Here's an excellent rundown of the common performance areas like this è fantastico quando si inizia. Include una spiegazione più approfondita del tracciamento delle modifiche che ho appena descritto.

1

select t nella scelta questo caso s tutti i campi di tipo noto. È fortemente digitato e meno soggetto agli stessi errori trovati in SQL.

Per esempio in SQL

INSERT INTO aTable 
SELECT * FROM AnotehrTable 

potrebbe fallire se AnotherTable cambiato, ma in Linq/Net non appare questa situazione.

Se si uniscono più tabelle, non è possibile eseguire un select * in Linq, si dovrà creare un tipo anonimo con tutti i tipi contenuti all'interno.

0

Direi che quello che stai facendo è l'equivalente di una dichiarazione SELECT *. È meglio restituire solo i campi richiesti ad es.

var myResult = from t in DataContext.MyEntity 
       where t.Country == 7 
       select new T 
       { 
        Field1 = t.Field1, 
        Field2 = t.Field2 
       } 
+0

E se volessi tutto in MyEntity? Vuoi creare un tipo anonimo identico a MyEntity? – cjk

+1

Avrei pensato (non testato) che il ritorno come l'OP ha suggerito, lo farebbe per te? – James

0

Si dovrebbe ancora indicare esplicitamente cosa si desidera selezionare. Se selezioni tutto, stai ancora tirando giù molti più dati di quelli di cui hai bisogno e man mano che vengono aggiunti nuovi elementi, tirerai anche quelli inutilmente. In generale, una buona pratica è tirare solo ciò di cui hai bisogno.

0

L'utilizzo di LINQ non allevierà il colpo di prestazioni di ottenere campi aggiuntivi.

Tuttavia, è impossibile generare un SELECT * FROM ... utilizzando LINQ to SQL. Il codice genererà una dichiarazione SELECT che nomina esplicitamente tutte le colonne definite nel modello; ignorerà tutte le modifiche al database.

Tuttavia, le prestazioni sono ancora un problema, quindi è necessario utilizzare un tipo anonimo se si utilizzano solo alcune delle colonne.

0

Potrebbe essere necessario farlo come nell'esempio, soprattutto se ciò che deve essere fatto è una modifica alla/e riga/e.

in SQL select * è diverso da linq perché linq restituirà sempre lo stesso numero di colonne (come definito nel dbml).

1

Il motivo per evitare SELECT * è che il database sottostante potrebbe cambiare e quindi potrebbero cambiare gli ordini delle colonne che potrebbero causare errori nel livello di accesso ai dati.

Non stai eseguendo un SELECT * dal tuo database, stai solo dicendo che vuoi "t" e tutto ciò che ne consegue. Non c'è niente di sbagliato in questo se è veramente ciò di cui hai bisogno.