2009-03-30 11 views
6

Necesito ayuda para la cláusula where where dinámica sobre tablas relacionales (una para muchas) en LinqToSql.Linq to Sql Necesita Dynamic Where Cláusula sobre tablas relacionales ¿Ayuda?

Condiciones de selección del usuario de la página. (hay 4 entradas que el usuario selecciona las cláusulas)

Por ejemplo, CompanyName y CompanyTitle de la tabla de clientes y OrderDate y ShipCity de la tabla de pedidos.

Pero usuario puede seleccionar uno o muchos de ellos desde la página interfaz y consulta dinámica se generan en el código subyacente y seleccione De LinqToSql.

Puede dar un tipo similar de ejemplo desde otras páginas web.

alt text http://www.yazgelistir.com/Makaleler/Resimler/1000001875_Linq-Class-Server.jpg

Respuesta

5

Comprobar el blog de ScottGu en el dynamic linq library. Creo que eso ayudará.

Aquí es un ejemplo de una consulta que golpea tanto a los clientes y tabla de pedidos:

 var query = 
    db.Customers. 
    Where("City = @0 and Orders.Count >= @1", "London", 10). 
    OrderBy("CompanyName"). 
    Select("new(CompanyName as Name, Phone)"); 

La consulta anterior procedían de la C# samples for Visual Studio. Descargue y busque en la carpeta \ LinqSamples \ DynamicQuery y encontrará más ejemplos.

+0

Visité también esta página. En los ejemplos, seleccionan de una tabla y crean una cláusula dynamic where sobre esto. –

2

Depende de cuán dinámico quieras que sea, como otros ya sugirieron el espacio de nombres System.Linq.Dynamic agrega una funcionalidad ordenada para redactar consultas donde las entidades/miembros (tablas/columnas) involucradas no se conocen en el momento del diseño. En este caso, parece que las entidades y los miembros involucrados ya son conocidos y solo tiene que alternar entre diferentes campos como criterio de cláusula where. Aquí está un ejemplo de ello:

from cust in dc.Customer 
join ord in dc.Order on cust.CustomerID equals ord.CustomerID 
where (companyName == null || cust.CompanyName == companyName) 
    and (companyTitle == null || cust.CompanyTitle == companyTitle) 
    and (orderDate == null || ord.OrderDate == orderDate) 
    and (shipCity == null || ord.ShipCity == shipCity) 
select new {cust, ord} 
+1

1 SQL estático no sería bueno. Para una consulta solo se creará UN plan de consulta. En podría, por ejemplo, funcionar bien, si proporciona P1, pero no está bien, si proporciona P2 o una combinación de P1 y P3. Tenía una consulta que unía varias tablas (5+) y los parámetros opcionales pertenecen a tablas diferentes. Un plan de consulta no funcionaba en SQL 2005 –

+1

@MichaelFreidgeim El ejemplo anterior * no * dará como resultado una única consulta SQL estática.L2S evalúa las partes que se pueden evaluar desde el lado del cliente y genera una consulta SQL que solo incluye las partes que la base de datos debe evaluar. Si, por ejemplo, el parámetro companyName es nulo, la parte del nombre de la compañía nunca llegará a la cláusula SQL where. Esta es una de las cosas bellas en Linq-to-SQL. – KristoferA

12

¿Está buscando algo como esto, donde se define la consulta "base", y luego evaluar los parámetros para determinar si una cláusula where es apropiado?

var result = (from x in context.X 
       select x); 

if(some condition) 
{ 
    result = result.AsQueryable().Where(x => x.companyName == name); 
} 
if(some other condition) 
{ 
    result = result.AsQueryable().Where(x => x.companyTitle == title); 
} 

//return result.ToList(); 
//return result.FirstOrDefault(); 
//return result.Count(); //etc 

Me di cuenta en uno de sus comentarios que mencionó que sus tablas no están unidas por una clave externa? No estoy seguro de cómo conseguir una relación de uno a muchos sin algún tipo de integridad referencial o relación?

+0

Soy un principiante de LINQ, pero ¿no recuperaría * todos * los datos de la base de datos y luego los filtraría progresivamente? Me parece que para grandes cantidades de datos sería más eficiente hacer que el DB haga el filtrado y devolver solo los datos que desee. – redcalx

+0

No, solo ejecuta la selección cuando realiza algo como ToList(), Count(), etc. – RobS

+0

Para aclarar: la base de datos devolverá todos los datos, y el cliente DB filtrará a través de las filas. Esto es distinto de pasar la cláusula WHERE al DB y devolver los datos filtrados al cliente DB. El código anterior hará lo anterior, posiblemente enviando un * lot * más datos de DB al cliente de base de datos de lo estrictamente necesario. – redcalx

0

RobS suministrado lo que creo que es la solución más atractiva. Sin embargo, este es el método que estaba usando, pero luego me di cuenta de que en realidad está realizando la primera consulta en su totalidad (Linq-To-SQL) y luego las siguientes cláusulas .Where() se realizan solo con LINQ. Entonces, esta no es una solución viable, ya que todo el conjunto de datos se enumera y luego se filtra en la memoria.

Corrígeme si me equivoco, pero esto es lo que he notado.

+0

¿Puedes publicar algún ejemplo? En mi experiencia (probado con SQL Profiler) la consulta no se ejecuta hasta que realizas algún tipo de operación, como ToList(), Count(), etc. – RobS

Cuestiones relacionadas