Necesito hacer una consulta LINQ2DataSet que haga una unión en más de un campo (como
var result = from x in entity
join y in entity2
on x.field1 = y.field1
and
x.field2 = y.field2
Todavía he encontrado una solución adecuada (puedo agregar las restricciones adicionales a una cláusula where, pero esto está lejos de ser una solución adecuada, o usar esta solución, pero eso supone un equijoin).
¿Es posible en LINQ unirse en múltiples campos en una sola combinación?
EDITAR
var result = from x in entity
join y in entity2
on new { x.field1, x.field2 } equals new { y.field1, y.field2 }
es la solución a la que me referí como asumir un equijoin arriba.
EDITAR más
Para responder a las críticas de que mi ejemplo original era un equijoin, reconozco que, mi requisito actual es un equijoin y ya he empleado la solución que mencioné anteriormente.
Sin embargo, estoy tratando de entender qué posibilidades y mejores prácticas tengo / debo emplear con LINQ. Voy a necesitar hacer una consulta de rango de fechas unirme con una ID de tabla pronto, y solo estaba adelantando ese problema, parece que tendré que agregar el rango de fechas en la cláusula where.
Gracias, como siempre, por todas las sugerencias y comentarios dados.
Respuestas:
La solución con el tipo anónimo debería funcionar bien. LINQ solo puede representar equijoins (con cláusulas de unión, de todos modos), y de hecho eso es lo que ha dicho que desea expresar de todos modos en función de su consulta original.
Si no le gusta la versión con el tipo anónimo por alguna razón específica, debe explicar esa razón.
Si desea hacer algo diferente a lo que originalmente solicitó, por favor, dé un ejemplo de lo que realmente quiere hacer.
EDITAR: respondiendo a la edición en la pregunta: sí, para hacer una unión de "intervalo de fechas", debe usar una cláusula where en su lugar. En realidad, son semánticamente equivalentes, por lo que es solo una cuestión de las optimizaciones disponibles. Los equijoins proporcionan una optimización simple (en LINQ to Objects, que incluye LINQ to DataSets) mediante la creación de una búsqueda basada en la secuencia interna; considérelo como una tabla hash de clave a secuencia de entradas que coinciden con esa clave.
Hacer eso con los rangos de fechas es algo más difícil. Sin embargo, dependiendo de exactamente lo que quiere decir con una "unión de rango de fechas", puede hacer algo similar , si planea crear "bandas" de fechas (por ejemplo, una por año) de modo que dos entradas que ocurran en el el mismo año (pero no en la misma fecha) debería coincidir, entonces puede hacerlo simplemente usando esa banda como clave. Si es más complicado, por ejemplo, un lado de la combinación proporciona un rango, y el otro lado de la combinación proporciona una sola fecha, que coincide si cae dentro de ese rango, que se manejaría mejor con una
where
cláusula (después de un segundofrom
cláusula) OMI. Podrías hacer algo de magia particularmente funky ordenando a un lado u otro que busque coincidencias de manera más eficiente, pero eso sería mucho trabajo: solo haría ese tipo de cosas después de verificar si el rendimiento es un problema.fuente
fuente
on new { X1= x.field1, X2= x.field2 } equals new { X1=y.field1, X2= y.field2 }
funcionóDebe hacer esto si los nombres de las columnas son diferentes en dos entidades.
fuente
Solo para completar esto con una sintaxis de cadena de método equivalente:
Si bien el último argumento
(x, y) => x
es lo que selecciona (en el caso anterior seleccionamosx
).fuente
Creo que una opción más legible y flexible es usar la función Where:
Esto también permite cambiar fácilmente de la unión interna a la unión izquierda agregando .DefaultIfEmpty ().
fuente
{ ... } equals new { ... }
sintaxis. LinqPad es una gran herramienta para ver cómo se comportan las expresiones (script SQL si se usa LINQ2SQL, árboles de expresiones, etc.)fuente
podrías hacer algo como (abajo)
fuente
Usando el operador de unión solo puede realizar equijoins. Se pueden construir otros tipos de combinaciones utilizando otros operadores. No estoy seguro de si la unión exacta que está intentando hacer sería más fácil usando estos métodos o cambiando la cláusula where. La documentación sobre la cláusula de unión se puede encontrar aquí . MSDN también tiene un artículo sobre operaciones de combinación con múltiples enlaces a ejemplos de otras combinaciones.
fuente
Si el nombre del campo es diferente en las entidades
fuente
Como una cadena de método completa que se vería así:
fuente
esto funciona para mi
fuente
Declare una clase (tipo) para contener los elementos que desea unir. En el siguiente ejemplo, declare JoinElement
fuente