2010-11-01 19 views
18

que realmente quieren hacer algo como esto:¿Cómo hacer un SQL "Donde existe" en LINQ to Entities?

Select * 
from A join B on A.key = B.key join C on B.key = C.key -- propagated keys 
where exists (select null from B where A.key = B.key and B.Name = "Joe") and 
     exists (select null from C where B.key = C.key and C.Name = "Kim") 

¿Cómo sería la declaración de LINQ parecerse utilizando Entity Framework 4 y C#?

Actualización:

Al parecer .Contains() producirá "en los que existe" resultados. Por lo tanto, otro intento
(no sé si esto va incluso compilar LOL):

var inner1 = from recordB in B 
      where recordB.Name = "Joe" 
      select recordB.key; 

var inner2 = from recordC in C 
      where recordC.Name = "Kim" 
      select recordC.key; 

var result = from recordA in A 
      where inner1.Contains(recordA.key) && 
        inner2.Contains(recordA.key) 
      select recordA; 

EDIT: WOW esto es lo que efectivamente trabajadas:

var result = from A in Products 
      where A.kfield1 == 1 && A.kfield2 == 2 && 
        (from B in Btable 
        where B.otherid == "Joe" && // field I want to select by 
          B.kfield1 == A.kfield1 &&  
          B.kfield2 == A.kfield2 // Can keep adding keys here 
        select A.identifier // unique identity field 
        ).Contains(A.identifier) && 
        (from C in Ctable 
        where C.otherid == "Kim" && // field I want to select by 
          C.kfield1 == A.kfield1 &&  
          C.kfield2 == A.kfield2 // Can keep adding keys here 
        select A.identifier // unique identity field 
        ).Contains(A.identifier) 
      select A; 

Esto produjo este SQL:

SELECT [t0].[identifier], [t0].* 
FROM [A] AS [t0] 
WHERE ([t0].[kfield1] = @p0) AND ([t0].[kfield2] = @p1) AND (EXISTS(
    SELECT NULL AS [EMPTY] 
    FROM [B] AS [t1] 
    WHERE ([t0].[identifier] = [t0].[identifier]) AND ([t1].[otherid] = @p2) AND 
      ([t1].[kfield1] = [t0].[kfield1]) AND 
      ([t1].[kfield2] = [t0].[kfield2]))) AND (EXISTS(
    SELECT NULL AS [EMPTY] 
    FROM [C] AS [t2] 
    WHERE ([t0].[identifier] = [t0].[identifier]) AND ([t2].[otherid] = @p3) AND 
      ([t2].[kfield1] = [t0].[kfield1]) AND 
      ([t2].[kfiekd2] = [t0].[kfield2]))) 

Que es lo que yo quería. Observe el [t0]. [Identificador] = [t0]. [Identificador], que filtra los valores nulos porque null no se compara con nada incluido él mismo (en SQL)

Respuesta

26

El método de extensión .Any() normalmente se asigna a exists.

+0

Eso es algo muy bueno de saber. Lo único que encontré en Internet hasta ahora ha sido .Contains() fuera de las respuestas de SO. He visto .Any() usé pero no puse dos y dos juntos. –

+0

Esta pregunta terminó mostrándome el código para hacer eso: http://stackoverflow.com/questions/4084102/how-would-i-improve-this-7-line-linq-query-hathat-acts-as-a- especificación –

0

Ha intentado agregar su acondicionador exists a tus uniones?

from a in context.AEntity 
Join B in context.BEntity on A.Key equals B.Key && B.Name == "Joe" 
Join C in context.CEntity on B.Key equals C.Key && C.Name == "Kim"; 

No estoy seguro si eso funcionará, pero vale la pena intentarlo.

+0

No, no funcionará. La cláusula 'on' solo acepta una expresión' igual' –

+0

Mirando nuevamente tu pregunta, no estoy seguro de entender por qué estás usando 'exists' en primer lugar. ¿Por qué no simplemente agregar 'donde B.Name ==" Joe "&& C.Name ==" Kim "'? –

+0

Porque trato de filtrar una consulta existente que tiene resultados anidados. Necesito filtrar por la parte anidada. La única forma en que puedo pensar para hacer eso es usar un Where exists (si esto es cierto, obtener el registro). –

Cuestiones relacionadas