Построение динамических запросов LINQ на основе значения Combobox - PullRequest
9 голосов
/ 30 января 2009

У меня есть поле со списком в Silverlight. Он имеет коллекцию значений, построенных на основе свойств одного из моих объектов LINQ-to-SQL (т. Е. Имени, адреса, возраста и т. Д.). Я хотел бы отфильтровать результаты по значению, выбранному в поле со списком.

Пример: скажем, я хочу, чтобы все с фамилией "Смит". Я бы выбрал «Фамилия» из выпадающего списка и введите Смит в элемент управления текстового поля. Обычно я бы написал запрос LINQ, похожий на ...

var query = из p в коллекции
где p.LastName == textbox.Text
выберите p;

Можно ли определить свойство динамически, возможно, с помощью Reflection? Что-то вроде

var query = из p в коллекции
где p. (DropDownValue) == textbox.Text
выберите p;

Ответы [ 3 ]

19 голосов
/ 31 января 2009

Предполагая, что:

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<> и генерирует код для построения дерева выражений , представляющего лямбду:

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 голос
/ 31 января 2009

Скотт Гатри (Scott Guthrie) имеет небольшую серию динамически построенных запросов LINQ to 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 голосов
/ 12 февраля 2009

Вы также можете использовать созданную мной библиотеку: http://tomasp.net/blog/dynamic-linq-queries.aspx. Вы бы сохранили свойства в ComboBox как лямбда-выражения, а затем просто написали:

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