2011-10-05 10 views
61

Estoy tratando de implementar una consulta en LINQ que usa una combinación externa izquierda con varias condiciones en la cláusula ON.LINQ Únase con varias condiciones en la cláusula On

Voy a usar el ejemplo de las dos tablas siguientes Proyecto (Proyectólo, Nombre del Proyecto) y el Grupo de (TaskID, projectId, taskName, Completado). Quiero ver la lista completa de todos los proyectos con sus respectivas tareas, pero solo aquellas tareas que se completan.

No puedo usar un filtro para Completed == true porque eso filtrará cualquier proyecto que no tenga tareas completadas. En su lugar, deseo agregar Completed == true a la cláusula ON de la unión para que se muestre la lista completa de proyectos, pero solo se mostrarán las tareas completadas. Los proyectos sin tareas completadas mostrarán una sola fila con un valor nulo para Tarea.

Aquí está la base de la consulta.

from t1 in Projects 
join t2 in Tasks 
on new { t1.ProjectID} equals new { t2.ProjectID } into j1 
from j2 in j1.DefaultIfEmpty() 
select new { t1.ProjectName, t2.TaskName } 

¿Cómo agrego && t2.Completed == true a la cláusula on?

Parece que no puedo encontrar ninguna documentación de LINQ sobre cómo hacer esto.

Respuesta

82

sólo tiene que nombrar la propiedad anónima la misma en ambos lados

on new { t1.ProjectID, SecondProperty = true } equals 
    new { t2.ProjectID, SecondProperty = t2.Completed } into j1 

Basado en los comentarios de @svick, aquí es otra aplicación que podría tener más sentido:

from t1 in Projects 
from t2 in Tasks.Where(x => t1.ProjectID == x.ProjectID && x.Completed == true) 
       .DefaultIfEmpty() 
select new { t1.ProjectName, t2.TaskName } 
+0

Eso parece ser una manera no obvia de hacerlo. No estoy seguro de entender lo que se supone que debe hacer. – svick

+1

@svick: el uso de tipos anónimos te permite unirte a múltiples criterios. Solo necesita asegurarse de que los nombres de las propiedades coincidan en ambos tipos. ¿No estás seguro de dónde viene la confusión? – Aducci

+0

La confusión es que realmente tiene más sentido como dos igualdades unidas por 'y', no una igualdad de algún objeto" extraño ". Y para demostrar mi punto, tu código es incorrecto. Para que funcione, tendrías que tener 'true' en el lado izquierdo y' t2.Complete' en el derecho. – svick

2

Usted no puedo hacerlo así. La cláusula join (y el método de extensión Join()) solo admite equijoins. Esa es también la razón, por qué usa equals y no ==. E incluso si pudiera hacer algo así, no funcionaría, porque join es una unión interna, no una combinación externa.

20

Aquí van con:

from b in _dbContext.Burden 
join bl in _dbContext.BurdenLookups on 
new { Organization_Type = b.Organization_Type_ID, Cost_Type = b.Cost_Type_ID } equals 
new { Organization_Type = bl.Organization_Type_ID, Cost_Type = bl.Cost_Type_ID } 
Cuestiones relacionadas