Perché usare LINQ Partecipare a una semplice relazione one-many?

Ho utilizzato LINQ per SQL ed Entity Framework per alcuni anni e ho sempre mappato le relazioni del mio database per generare le proprietà di navigazione pertinenti. E uso sempre le proprietà di navigazione.

Mi sto perdendo qualcosa?

Se avessi una relazione di tipo – Category->Products di tipo uno-molti, userei

 var redProducts = context.Category.Single(c => c.Name = "red").Products; 

Vedo regolarmente persone che fanno collegamenti manuali, in tutto questo sito, in progetti online e in vari altri siti web.

 var employer = from category in context.Categories join product in context.Products on category.CategoryId equals product.CategoryId where category.Name == "red" select product; 

Quindi, perché? Quali sono i vantaggi dell’uso di questa syntax Join ?

Di solito è un errore.

@George ha ragione che i tuoi due esempi sono funzionalmente diversi in un modo che non ha nulla a che fare con join vs non- join , comunque. Ma potresti scrivere altrettanto facilmente:

 var redProducts = context.Category .Where(c => c.Name == "red") .SelectMany(c => c.Products); 

… che è funzionalmente identico (ma superiore a un POV di leggibilità e manutenibilità) al tuo esempio di join .

Potrebbe derivare dal porting del vecchio codice su linq2sql.

Tuttavia, i due frammenti di codice non sono funzionalmente uguali.

Single genererà un’eccezione, mentre join produce una raccolta vuota in caso di record mancante.

Quindi, un codice uguale senza l’utilizzo di join sarebbe:

 from c in context.Categories where c.Name == "red" from p in c.Products select p; 

o

 context.Categories.Where(c=>c.Name == "red").SelectMany(c=>c.Products); 

Le unioni sono probabilmente più comuni per le persone che provengono dalla mentalità relazionale piuttosto che da quella orientata agli oggetti. Se pensi al tuo problema spaziale da una prospettiva orientata agli oggetti, è molto più naturale lavorare con le relazioni in cui puoi mettere a punto la navigazione: Employee.Customers.Orders.OrderItems.OrderItem piuttosto che affrontare un mucchio di join. Il white paper ADO.vNext originale ha fatto un buon lavoro discutendo i vantaggi dell’uso del modello e delle associazioni piuttosto che dei join per gestire i modelli concettuali. Sfortunatamente, non riesco a trovare quel documento a questo punto.

Per me, i join vengono utilizzati al meglio quando non si hanno associazioni naturali tra quadro. Ad esempio, se si sta tentando di unire elementi su chiavi non naturali (ad esempio aderendo a Customer.State e Shipping.State ) è necessario utilizzare la syntax di join (o SelectMany ) piuttosto che creare associazioni tra le quadro in questo caso.

Una cosa da tenere presente è che la syntax di join e l’utilizzo di associazioni possono causare differenze nel tipo di join generati dal provider. In genere un join si traduce in un join interno ed esclude gli elementi in cui non vi è alcuna corrispondenza su entrambi i lati del join. Per eseguire un join esterno (a sinistra), si utilizza l’estensione DefaultIfEmpty .

Navigare attraverso le associazioni in una relazione 1-0 .. *, d’altra parte, tipicamente si traduce in join Right Outer perché la collezione figlio potrebbe legittimamente essere vuota e si vorrebbe includere il genitore anche se il figlio non esisteva. Dovresti usare !Any() trappola per i casi in cui non ci sono record figlio.