Suponiendo que tengo una combinación externa izquierda como tal:
from f in Foo
join b in Bar on f.Foo_Id equals b.Foo_Id into g
from result in g.DefaultIfEmpty()
select new { Foo = f, Bar = result }
¿Cómo expresaría la misma tarea usando métodos de extensión? P.ej
Foo.GroupJoin(Bar, f => f.Foo_Id, b => b.Foo_Id, (f,b) => ???)
.Select(???)
c#
linq-to-sql
lambda
LaserJesus
fuente
fuente
GroupJoin
, la unión externa izquierda, laSelectMany
parte solo es necesaria dependiendo de lo que desee seleccionar.Dado que esta parece ser la pregunta SO de facto para las uniones externas izquierdas utilizando la sintaxis del método (extensión), pensé que agregaría una alternativa a la respuesta actualmente seleccionada que (al menos en mi experiencia) ha sido más comúnmente lo que soy después
Para mostrar la diferencia usando un conjunto de datos simple (suponiendo que nos unamos a los valores mismos):
La opción 2 es fiel a la definición típica de combinación externa izquierda, pero como mencioné anteriormente, a menudo es innecesariamente compleja dependiendo del conjunto de datos.
fuente
Single
comprobación fácilmente en medio de una unión.SingleOrDefault
Sin embargo, es una forma más "correcta" de demostrar esta OMI.El método de unión de grupo no es necesario para lograr la unión de dos conjuntos de datos.
Unir internamente:
Para la unión izquierda simplemente agregue DefaultIfEmpty ()
EF y LINQ to SQL se transforman correctamente a SQL. Para LINQ to Objects es mejor unirse usando GroupJoin ya que internamente usa Lookup . Pero si está consultando DB, entonces omitir GroupJoin es AFAIK como performant.
Personlay para mí de esta manera es más legible en comparación con GroupJoin (). SelectMany ()
fuente
Puede crear un método de extensión como:
fuente
Mejorando la respuesta de Ocelot20, si tiene una tabla que le queda unida externamente donde solo desea 0 o 1 filas, pero podría tener varias, debe Ordenar su tabla unida:
De lo contrario, la fila que obtenga en la unión será aleatoria (o más específicamente, cualquiera que sea la base de datos que encuentre primero).
fuente
Al convertir la respuesta de Marc Gravell en un método de extensión, hice lo siguiente.
fuente
Si bien la respuesta aceptada funciona y es buena para Linq to Objects, me molestó que la consulta SQL no sea solo una combinación externa izquierda.
El siguiente código se basa en el Proyecto LinkKit que le permite pasar expresiones e invocarlas a su consulta.
Se puede usar de la siguiente manera
fuente
Hay una solución fácil para esto
Simplemente use. HasValue en su Seleccionar
Muy fácil, no es necesario unirse al grupo ni nada más.
fuente