2010-07-10 12 views
174

He visto muchos ejemplos en los ejemplos de LINQ a SQL sobre cómo hacer una combinación en la sintaxis de la consulta, pero me pregunto cómo hacerlo con la sintaxis del método. Por ejemplo, cómo podría yo hacer lo siguiente¿Cómo hacer una unión en linq a sql con la sintaxis del método?

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()? ¿Alguien puede ilustrar u ofrecer otro ejemplo simple?

Respuesta

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

sería equivalente a:

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

Como se puede ver, cuando se trata de uniones, sintaxis de la consulta es por lo general mucho más legible que la sintaxis lambda.

121

Justin ha mostrado correctamente la expansión en el caso donde la unión es seguida por un select. Si tiene algo más, se vuelve más complicado debido a identificadores transparentes - el mecanismo que el compilador C# usa para propagar el alcance de ambas mitades de la unión.

Así que para cambiar el ejemplo de Justin ligeramente:

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 } 

se convertirían en algo como esto:

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

El z aquí es el identificador transparente - sino porque es transparente, no se puede verlo en la consulta original :)

4

Para agregar a las otras respuestas aquí, si desea crear un nuevo objeto de un th ird diferente tipo con una cláusula where (p. uno que no es su objeto Entidad marco) se puede hacer esto:

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; 

}  

Prestar especial atención al objeto intermedio que se crea en el caso de las cláusulas y Select.

Tenga en cuenta que aquí también buscamos cualquier objeto unido que tenga una propiedad1 que coincida con uno de los que están en la lista de entrada.

Sé que esto es un poco más complejo que lo que el asker original estaba buscando, pero espero que ayude a alguien.

Cuestiones relacionadas