2011-10-14 19 views
13

Hay numerosas publicaciones relacionadas con LINQ y múltiples uniones. No he encontrado ninguna solución para la unión que me gustaría hacer.LINQ to Entity: múltiples condiciones de unión

El SQL equivalente sería algo como esto:

SELECT * FROM table1 a 
LEFT JOIN table2 b ON a.col1 = b.key1 AND 
a.col2 = b.key2 AND 
b.from_date <= now() AND 
b.deleted = 0; 

Aquí está una de las numerosas consultas LINQ He intentado

var query = (from x in context.table1 
      join y in context.table2 on new {x.col1, x.col2} equals {b.key1, b.key2} 
      into result 
      from result...... 

¿En qué puedo añadir las condiciones additonal de la fecha y eliminados ¿bandera? Si uso las condiciones .Where, esto se trata como una unión interna, no como una combinación izquierda.

Respuesta

32

Otra forma podría ser como

var query = (from x in context.table1 
      join y in context.table2 on 
      new { 
        Key1 = x.col1, 
        Key2 = x.col2 
        Key3 = true, 
        Key4 = true 
       } 
      equals 
      new { 
        Key1 = y.key1, 
        Key2 = y.key2, 
        Key3 = y.from_date< DateTime.Now, 
        Key4 = !y.deleted 
       } 
      into result 
from r in result.DefaultIfEmpty() 
select new {x.Something, r.Something} 
1

¿No podría simplemente filtrar el primer conjunto de resultados con una segunda consulta?

var query = (from x in context.table1 
      join y in context.table2 on new {x.col1, x.col2} equals {b.key1, b.key2} 
      into result 
query = from x in query 
     where ... 

¿Eso funcionaría?

11

LINQ es compatible con la sintaxis de la combinación y el mayor ANSI-82 DONDE sintaxis. Usando el último, puede hacer lo que busca desde

var nowTime = DateTime.Now; 
var query = from a in context.table1 
      from b in context.table2 
      where a.col1 == b.key1 
       && a.col2 == b.key2 
       && b.from_date < nowTime 
       && b.deleted == false 
      select ???; 

Alternativamente, podría usar un híbrido de where y join. (Date cuenta que el orden en la consulta LINQ no tiene que imitar lo que se hace en SQL y el orden es más flexible.)

var nowTime = DateTime.Now; 
var query = from b in context.table2 
      where b.from_date < nowTime 
       && b.deleted == false 
      join a on new {b.key1, b.key2} equals new {a.col1, a.col2} 
      select ???; 
0

tuve un problema con designación de propiedades en objeto anónimo:

var subscriptions = context.EmailSubscription.Join(context.EmailQueue, 
        es => new { es.Id, 9 }, 
        eq => new { eq.EmailSubscriptionId, eq.EmailTemplateId }, 
        (es, eq) => new { es.Id, eq.Id } 
       ).ToList(); 

El compilador no estaba contento, por lo tanto, la respuesta anterior me ayuda a descubrir qué estaba mal y aquí está mi solución de trabajo. Me tomó algo de tiempo encontrar el error estúpido :):

var subscriptions = context.EmailSubscription.Join(context.EmailQueue, 
        es => new { EmailSubscriptionId = es.Id, EmailTemplateId = 9 }, 
        eq => new { eq.EmailSubscriptionId, eq.EmailTemplateId }, 
        (es, eq) => new { es.Id, eq.Id } 
       ).ToList(); 
Cuestiones relacionadas