2011-11-24 14 views
10

Tengo una tabla con una asignación de uno a muchos a una tabla que tiene un mapeo de muchos a muchos a otra tabla. Me gustaría hacer lo siguiente:linq a entidades, a where where where cláusula? (interno donde)

var results = context.main_link_table 
        .Where(l => l.some_table.RandomProperty == "myValue" && 
          l.some_table.many_to_many_table 
          .Where(m => m.RandomProperty == "myValue")); 

¿Cómo puedo lograr esto? La primera parte funcionará, pero cuando la intento sin el 'WHERE interno', no puedo acceder a las propiedades de many_to_many_table, pero el "inner where" obviamente no compilará. Básicamente quiero lograr algo parecido a la siguiente consulta SQL:

SELECT * from main_link_table 
INNER JOIN some_table AS t1 ON t1.association = main_link_table.association 
INNER JOIN many_to_many_table AS t2 ON t2.association = some_table.association 
WHERE t1.RandomProperty = 'MyValue' AND t2.RandomProperty = 'MyValue' 

Es aparentemente simple, pero no puedo encontrar una manera de lograrlo en una sola línea de LINQ - el uso de múltiples líneas para lograr el efecto deseado vuelve demasiado muchos resultados y termino teniendo que recorrerlos. También probé cosas como:

var results = main_link_tbl.Include("some_table.many_to_many_table") 
          .Where(l => l.some_table.many_to_many_table.<property> 
             == "MyValue") 

Pero en este momento no puedo seleccionar una propiedad de many_to_many_table menos que agrego un FirstOrDefault(), que anula el efecto ya que no será buscar a través de todos los registros.

Lo que hizo el trabajo, pero requiere múltiples líneas de código y en el fondo devuelve demasiados resultados en la consulta SQL construida por el marco LINQ a las entidades:

var results = db.main_link_table.Include("some_table") 
           .Include("some_table.many_to_many_table") 
           .Where(s => s.some_table.RandomProperty 
              == "myValue") 
           .Select(s => s.some_table); 

foreach(var result in results) { 
    var match_data = result.Where(s => s.many_to_many_table.RandomProperty 
             == "myValue"); 
} 

Esta pieza de código devolverá toda filas dentro de una_tabla que coincide con la primera condición Donde y luego aplica la siguiente condición Donde, mientras que obviamente solo necesito una sola fila donde la many_to_many_table.RandomProperty es igual a myValue.

Respuesta

16

Debería funcionar si cambia el interior Where a Any:

var results = context.main_link_table 
        .Where(l => l.some_table.RandomProperty == "myValue" && 
           l.some_table.many_to_many_table 
            .Any(m => m.RandomProperty == "myValue")); 
+0

funciona como un encanto. – L2Eer

+0

muy hermoso. – qakmak

4

Si quieres unirte, ¿por qué no haces una unión?

var query = from main in context.MainLinks 
      join t1 in context.Some on main.Association equals t1.Association 
      where t1.RandomProperty == "MyValue" 
      join t2 in context.ManyToMany on t1.Association equals t2.Association 
      where t2.RandomProperty == "MyValue" 
      select new { main, t1, t2 }; 

Eso debería lograr exactamente lo que hace su SQL ...

1
from link in db.main_link_table 
join s in db.some_table on link.association1 = s.association 
join m in db.many_to_many_table on link.association2 = m.association 
where s.X = 'MyValue' AND m.Y = 'MyValue' 
select m; // or s or link or both 3 as you want