2009-01-30 28 views
9

Tengo un cuadro combinado en Silverlight. Tiene una colección de valores construidos a partir de las propiedades de uno de mis objetos LINQ-to-SQL (es decir, Nombre, Dirección, Edad, etc.). Me gustaría filtrar mis resultados según el valor seleccionado en un cuadro combinado.Creación de consultas LINQ dinámicas basadas en el valor de Combobox

Ejemplo: Digamos que quiero que todos tengan el apellido "Smith". Seleccionaría 'Apellido' de la lista desplegable e ingresaría a smith en un control de cuadro de texto. Normalmente me gustaría escribir una consulta LINQ similar a ...

var query = de p en la colección
donde p.LastName == TextBox.Text
seleccione p;

¿Es posible decidir dinámicamente la propiedad, quizás utilizando Reflection? Algo así como

var query = de p en la colección
donde p (DropDownValue) == TextBox.Text
seleccione p.;

Respuesta

19

Suponiendo:

public class Person 
{ 
    public string LastName { get; set; } 
} 

IQueryable<Person> collection; 

su consulta:

var query = 
    from p in collection 
    where p.LastName == textBox.Text 
    select p; 

significa lo mismo que:

var query = collection.Where(p => p.LastName == textBox.Text); 

que el compilador traduce de un método de extensión a:

var query = Queryable.Where(collection, p => p.LastName == textBox.Text); 

El segundo parámetro de Queryable.Where es una Expression<Func<Person, bool>>. El compilador entiende el tipo Expression<> y genera código para construir una representación de la expression tree lambda:

using System.Linq.Expressions; 

var query = Queryable.Where(
    collection, 
    Expression.Lambda<Func<Person, bool>>(
     Expression.Equal(
      Expression.MakeMemberAccess(
       Expression.Parameter(typeof(Person), "p"), 
       typeof(Person).GetProperty("LastName")), 
      Expression.MakeMemberAccess(
       Expression.Constant(textBox), 
       typeof(TextBox).GetProperty("Text"))), 
     Expression.Parameter(typeof(Person), "p")); 

Eso es lo que significa la sintaxis de la consulta.

Puede llamar a estos métodos usted mismo. Para cambiar la propiedad en comparación, sustituir este:

typeof(Person).GetProperty("LastName") 

con:

typeof(Person).GetProperty(dropDown.SelectedValue); 
+0

Brillante Respuesta ... Justo lo que estaba buscando ... Gracias Brian ... –

1

Scott Guthrie tiene una serie corta de LINQ dyamically construido para consultas SQL:

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

Esa es la manera fácil ... entonces no hay otra manera que es un poco más complicado:

http://www.albahari.com/nutshell/predicatebuilder.aspx

+0

Estos artículos son perfectos si está trabajando con aplicaciones ASP.NET, es bueno saberlo, gracias por eso, desafortunadamente con Silverlight, System. Windows.Threading no es compatible con algunos de los métodos utilizados en la Biblioteca LINQ dinámica –

+0

Ah ... la etiqueta de Silverlight estaba en mi punto ciego. – Kev

0

También puede utilizar la biblioteca creé: http://tomasp.net/blog/dynamic-linq-queries.aspx.Guardaría las propiedades en ComboBox como expresiones lambda y luego solo escribiría:

var f = (Expression<Func<Product, string>>)comboBox.SelectedValue; 
var query = 
    from p in collection 
    where f.Expand(textBox.Text) 
    select p; 
Cuestiones relacionadas