2009-01-30 12 views
9

Ho una casella combinata in Silverlight. Ha una collezione di valori costruita con le proprietà di uno dei miei oggetti LINQ-to-SQL (ad es. Nome, Indirizzo, Età, ecc.). Vorrei filtrare i miei risultati in base al valore selezionato in una casella combinata.Creazione di query LINQ dinamiche basate sul valore di Combobox

Esempio: dire che voglio che tutti abbiano un cognome "Smith". Selezionerei "Cognome" dall'elenco a discesa e inserisco Smith in un controllo casella di testo. Normalmente avrei scrivere una query LINQ simile a ...

var query = da p di raccolta
dove p.LastName == TextBox.Text
selezionare p;

È possibile decidere dinamicamente la proprietà, magari utilizzando Reflection? Qualcosa di simile

var query = da p in collezione
dove p (DropDownValue) == TextBox.Text
selezionare p.;

risposta

19

Assumendo:

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

IQueryable<Person> collection; 

la ricerca:

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

lo stesso significato:

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

cui il compilatore traduce da un metodo di estensione per:

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

Il secondo parametro di Queryable.Where è un Expression<Func<Person, bool>>. Il compilatore capisce il tipo Expression<> e genera il codice per costruire un expression tree che rappresenta il 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")); 

Questo è ciò che significa la sintassi di query.

Sei libero di chiamare questi metodi tu stesso. Per modificare la proprietà rispetto, sostituire questo:

typeof(Person).GetProperty("LastName") 

con:

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

Risposta brillante ... Proprio quello che stavo cercando ... Grazie Brian ... –

1

Scott Guthrie ha una breve serie su LINQ dyamically costruito per query SQL:

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

Questo è il modo più semplice ... poi c'è un altro modo che è un po 'più complesso:

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

+0

Questi articoli sono perfetti se state lavorando con applicazioni ASP.NET, buono a sapersi, grazie per questo, purtroppo con Silverlight, System. Windows.Threading non supporta alcuni dei metodi utilizzati nella libreria Dynamic LINQ –

+0

Ah ... il tag Silverlight era nel mio blind. – Kev

0

È inoltre possibile utilizzare la libreria che ho creato: http://tomasp.net/blog/dynamic-linq-queries.aspx.Memorizzereste le proprietà in ComboBox come espressioni lambda e quindi scrivete:

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