por qué no podrían los diseñadores de LINQ hacer las cosas simples (más sql como)
que podrían tener. Pero su definición de programador simple (como un programador sql) no es lo mismo que la definición simple del programador OO. Linq (en C#) es una tecnología de consulta para programadores OO, primero. Un ejemplo de esto es por qué select viene el último. Eso es para cumplir con las reglas de alcance en C# y el soporte intellisense en el editor.
Estos programadores quizás no obtengan LEFT JOIN
(y se confunden realmente si dice LEFT OUTER JOIN
- pensando que hay alguna diferencia, como una hereda de la otra).
Lo que sí entienden es GROUP JOIN
, que se comporta de manera similar.
List<int> myInts = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
List<int> myOtherInts = new List<int>() { 1, 3, 5, 7, 9, 11, 13 };
//
var query = from i in myInts
join j in myOtherInts on i equals j into g
select new {key = i, myGroup = g};
//
foreach (var grouping in query)
{
Console.WriteLine("--{0}", grouping.key);
foreach (var x in grouping.myGroup)
Console.WriteLine(x);
}
Todo lo que hace es DefaultIfEmpty
cosas desempaquetar el grupo - aplanando los resultados en fila/columna de forma - lejos de forma jerárquica natural del programador OO.DefaultIfEmpty
no es semánticamente necesario para llegar a los resultados.
Ésta es la misma consulta en forma de método - la que el compilador genera a partir de lo anterior y que yo prefiero:
var query = myInts.GroupJoin(
myOtherInts,
i => i,
j => j,
(i, g) => new { key = i, myGroup = g }
);
Podría decir que en términos de su ejemplo?
Esta consulta le brinda a los clientes, con sus pedidos como una colección adjunta. La colección de pedidos puede estar vacía. Si tiene 50 clientes y 1000 pedidos, tendrá 50 clientes en el resultado.
from c in dc.Customers
join o in dc.Orders on c.custid equals o.custid into someOrders
select new CustomerWithOrders()
{theCustomer = c, theOrders = someOrders};
Esta consulta le proporciona una fila CustomerOrder. Si un cliente tiene 5 pedidos, el cliente aparecerá 5 veces, cada vez que coincida con un pedido diferente. Si el cliente tiene 0 pedidos, el cliente aparecerá una vez que coincida con un pedido nulo. Si tiene 50 clientes y 1000 pedidos, tendrá 50-1049 filas después de la unión y el significado de un elemento en el resultado es difícil de definir.
from c in dc.Customers
join o in dc.Orders on c.custid equals o.custid into temp
from x in temp.DefaultIfEmpty()
select new CustomerOrderHybrid() {theCustomer = c, theOrder = x}
Si se implementan left join
, se requeriría la forma resultado del segundo ejemplo. Una vez que utilicé el group join
, que es mejor, tampoco implementaría el left join
en un solo paso. La configuración jerárquica de los resultados de las consultas es excelente.
Sí, supuse que probablemente era difícil, pero me gustaría saber por qué fue difícil ... – user52110
Linq no es azúcar sintáctica. el compilador no traduce nada EN expresiones lambda. Nadie dijo nada sobre la generación de SQL en la pregunta. -1 –
OK, no estoy seguro de que sea lambdas per se, pero linq ES azúcar sintáctico, y el compilador lo traduce en llamadas a métodos. –