Como fazer uma junção no linq to sql com sintaxe de método?


193

Eu já vi muitos exemplos nos exemplos LINQ to SQL sobre como fazer uma junção na sintaxe de consulta, mas estou pensando em como fazer isso com a sintaxe do método? Por exemplo, como posso fazer o seguinte

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

com um .Join()? Alguém pode ilustrar ou fornecer outro exemplo simples?

Respostas:


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

Seria equivalente a:

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

Como você pode ver, quando se trata de junções, a sintaxe da consulta geralmente é muito mais legível que a sintaxe lambda.


128

Justin mostrou corretamente a expansão no caso em que a junção é apenas seguida por a select. Se você tiver outra coisa, isso se tornará mais complicado devido a identificadores transparentes - o mecanismo que o compilador C # usa para propagar o escopo das duas metades da junção.

Então, para mudar um pouco o exemplo de 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 }

seria convertido em algo como isto:

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 });

O zaqui é o identificador transparente - mas, como é transparente, você não pode vê-lo na consulta original :)


5

Para adicionar outras respostas aqui, se você quiser criar um novo objeto de um terceiro tipo diferente com uma cláusula where (por exemplo, uma que não seja seu objeto do Entity Framework), faça o seguinte:

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;

}    

Preste atenção especial ao objeto intermediário criado nas cláusulas Where e Select.

Observe que aqui também procuramos objetos unidos que tenham uma propriedade1 que corresponda a um na lista de entrada.

Sei que isso é um pouco mais complexo do que o solicitante original estava procurando, mas espero que ajude alguém.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.