Building Dynamic LINQ Queries based on Combobox Value
Asked Answered
D

3

9

I have a combo box in Silverlight. It has a collection of values built out of the properties of one of my LINQ-to-SQL objects (ie Name, Address, Age, etc...). I would like to filter my results based off the value selected in a combo box.

Example: Say I want everyone with a last name "Smith". I'd select 'Last Name' from the drop down list and enter smith into a textbox control. Normally I would write a LINQ query similar to...

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

Is it possible to decide the property dynamically, maybe using Reflection? Something like

var query = from p in collection
where p.(DropDownValue) == textbox.Text
select p;

Deery answered 30/1, 2009 at 20:29 Comment(0)
A
19

Assuming:

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

IQueryable<Person> collection;

your query:

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

means the same as:

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

which the compiler translates from an extension method to:

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

The second parameter of Queryable.Where is an Expression<Func<Person, bool>>. The compiler understands the Expression<> type and generates code to build an expression tree representing the 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"));

That is what the query syntax means.

You are free to call these methods yourself. To change the compared property, replace this:

typeof(Person).GetProperty("LastName")

with:

typeof(Person).GetProperty(dropDown.SelectedValue);
Antecedence answered 30/1, 2009 at 23:41 Comment(0)
D
1

Scott Guthrie has a short series on dyamically built LINQ to SQL queries:

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

That's the easy way...then there's another way that's a bit more involved:

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

Disproof answered 30/1, 2009 at 21:0 Comment(2)
These articles are perfect if you're working with ASP.NET applications, good to know, thanks for that, unfortunately with Silverlight, System.Windows.Threading does not support some of the methods used in the Dynamic LINQ LibraryDeery
Ah...the Silverlight tag was in my blindspot.Disproof
D
0

You can also use the library I created: http://tomasp.net/blog/dynamic-linq-queries.aspx. You would store the properties in ComboBox as lambda expressions and then just write:

var f = (Expression<Func<Product, string>>)comboBox.SelectedValue;
var query =
    from p in collection
    where f.Expand(textBox.Text)
    select p;
Deutsch answered 12/2, 2009 at 1:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.