Come eseguire un join in linq to sql con la sintassi del metodo?


193

Ho visto molti esempi negli esempi LINQ to 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 segue

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?

Risposte:


285
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 puoi vedere, quando si tratta di join, la sintassi della query è in genere molto più leggibile della sintassi lambda.


129

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

Quindi, per cambiare leggermente l'esempio di Justin:

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 convertito in qualcosa del genere:

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 zqui è l'identificativo trasparente - ma perché è trasparente, non è possibile vedere nella query originale :)


5

Per aggiungere qui le altre risposte, se si desidera creare un nuovo oggetto di un terzo tipo diverso con una clausola where (ad es. Uno che non è l'oggetto Entity Framework) è possibile fare ciò:

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 creato nelle clausole Where e Select.

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

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.