2009-01-30 70 views
9

我在Silverlight中有一个组合框。它有一个由我的LINQ-to-SQL对象(即Name,Address,Age等)的属性构建的值的集合。我想根据在组合框中选择的值过滤我的结果。基于Combobox值构建动态LINQ查询

例如:假设我希望每个人都有姓氏“Smith”。我会从下拉列表中选择“姓氏”,并将smith输入到文本框控件中。通常我会在收集
其中p.LastName == textbox.Text
的选择P写LINQ查询类似...

VAR的查询=从磷;

是否有可能动态地决定属性,也许使用反射?像

变种查询=从对在收集
其中p(DropDownValue)== textbox.Text
选择页。;

回答

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<>类型,并生成代码来构建表示拉姆达一个expression tree

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

斯科特·格思里有dyamically内置LINQ短的一系列SQL查询:

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

这是最简单的方式......再有另一种方式,这是一个有点更复杂:

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

+0

这些文章是完美的,如果你使用ASP.NET应用程序,好知道,感谢您的工作,遗憾的是使用Silverlight,系统。 Windows.Threading不支持动态LINQ库中使用的一些方法 – 2009-02-02 16:46:20

+0

啊... Silverlight标签在我的盲点。 – Kev 2009-02-02 17:32:25

0

您也可以使用我创建库:http://tomasp.net/blog/dynamic-linq-queries.aspx。你会在组合框的属性存储为lambda表达式,然后就写:

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