基于下拉框值构建动态LINQ查询

9
我在Silverlight中有一个下拉框,它的值集合是由我的LINQ-to-SQL对象的属性(例如:名称、地址、年龄等)构建而成。我想根据下拉框选定的值来过滤结果。
例如:我想要所有姓“史密斯”的人。我会从下拉列表中选择“姓氏”,然后在文本框中输入smith。通常情况下,我会编写类似于以下的LINQ查询语句...
var query = from p in collection where p.LastName == textbox.Text select p;
是否可以动态地决定属性,也许使用反射?像这样:
var query = from p in collection where p.(DropDownValue) == textbox.Text select p;
3个回答

19

假设:

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

IQueryable<Person> collection;

你的查询:

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

意思相同:

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

编译器将扩展方法转换为:

var query = Queryable.Where(collection, p => p.LastName == textBox.Text);
Queryable.Where的第二个参数是一个Expression<Func<Person, bool>>类型。编译器可以理解Expression<>类型,并生成代码来构建表示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"));

这就是查询语法的含义。

你可以自由地调用这些方法。如果想要改变所比较的属性,请替换掉这段代码:

typeof(Person).GetProperty("LastName")

使用:

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

1

如果你正在使用ASP.NET应用程序,这些文章非常完美,很好知道,谢谢。不幸的是,在Silverlight中,System.Windows.Threading不支持Dynamic LINQ Library中使用的某些方法。 - Steve G.
啊...Silverlight标签在我视线盲区。 - Kev

0

你也可以使用我创建的库:http://tomasp.net/blog/dynamic-linq-queries.aspx。你可以将属性存储在ComboBox中成为lambda表达式,然后只需编写以下代码:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接