2010-07-10 10 views
174

Ho visto molti esempi in LINQ su esempi SQL su come eseguire un join nella sintassi della query, ma mi chiedo come farlo con la sintassi del metodo? Ad esempio, come potrei fare quanto segueCome si fa un join in linq a sql con la sintassi del metodo?

var result = from sc in enumerableOfSomeClass 
      join soc in enumerableOfSomeOtherClass 
      on sc.Property1 equals soc.Property2 
      select new { SomeClass = sc, SomeOtherClass = soc } 

con un .Join()? Qualcuno può illustrare o fornire un altro semplice esempio?

risposta

254
var result = from sc in enumerableOfSomeClass 
      join soc in enumerableOfSomeOtherClass 
      on sc.Property1 equals soc.Property2 
      select new { SomeClass = sc, SomeOtherClass = soc }; 

sarebbe equivalente a:

var result = enumerableOfSomeClass 
    .Join(enumerableOfSomeOtherClass, 
      sc => sc.Property1, 
      soc => soc.Property2, 
      (sc, soc) => new 
         { 
          SomeClass = sc, 
          SomeOtherClass = soc 
         }); 

Come si può vedere, quando si tratta di giunzioni, sintassi di query è di solito molto più leggibile di sintassi lambda.

121

Justin ha correttamente mostrato l'espansione nel caso in cui il join è appena seguito da un select. Se hai qualcos'altro, diventa più difficile a causa degli identificatori trasparenti - il meccanismo utilizzato dal compilatore C# per propagare l'ambito di entrambe le metà del join.

Quindi, per modificare l'esempio di Justin leggermente:

var result = from sc in enumerableOfSomeClass 
      join soc in enumerableOfSomeOtherClass 
      on sc.Property1 equals soc.Property2 
      where sc.X + sc.Y == 10 
      select new { SomeClass = sc, SomeOtherClass = soc } 

sarebbe trasformato in qualcosa di simile:

var result = enumerableOfSomeClass 
    .Join(enumerableOfSomeOtherClass, 
      sc => sc.Property1, 
      soc => soc.Property2, 
      (sc, soc) => new { sc, soc }) 
    .Where(z => z.sc.X + z.sc.Y == 10) 
    .Select(z => new { SomeClass = z.sc, SomeOtherClass = z.soc }); 

Il z Ecco l'identificatore trasparente - ma perché è trasparente, non è possibile vederlo nella query originale :)

4

Per aggiungere altre risposte qui, se si desidera creare un nuovo oggetto di un th un tipo diverso con una clausola where (ad es. uno che non è l'oggetto Entity Framework) si può fare questo:

public IEnumerable<ThirdNonEntityClass> demoMethod(IEnumerable<int> property1Values) 
{ 
    using(var entityFrameworkObjectContext = new EntityFrameworkObjectContext) 
    { 
     var result = entityFrameworkObjectContext.SomeClass 
      .Join(entityFrameworkObjectContext.SomeOtherClass, 
       sc => sc.property1, 
       soc => soc.property2, 
       (sc, soc) => new {sc, soc}) 
      .Where(s => propertyValues.Any(pvals => pvals == es.sc.property1) 
      .Select(s => new ThirdNonEntityClass 
      { 
       dataValue1 = s.sc.dataValueA, 
       dataValue2 = s.soc.dataValueB 
      }) 
      .ToList(); 
    } 

    return result; 

}  

prestare particolare attenzione all'oggetto intermedio che viene creato nella Dove e Select clausole.

Si noti che qui cerchiamo anche tutti gli oggetti uniti che hanno una proprietà1 che corrisponde a uno di quelli nella lista di input.

So che questo è un po 'più complesso di quello che cercava il richiedente originale, ma spero che possa aiutare qualcuno.

Problemi correlati