2009-01-30 69 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;