Общий предикат запроса LINQ? - PullRequest
18 голосов
/ 24 сентября 2008

Не уверен, возможно ли это, или я правильно выражаю то, что ищу, но у меня в библиотеке есть следующий фрагмент кода, и я хотел бы попрактиковаться в СУХОЙ. У меня есть набор таблиц SQL Server, которые я запрашиваю на основе простого пользовательского поля поиска аля Google. Я использую LINQ для составления окончательного запроса на основе того, что в строке поиска. Я ищу способ использовать дженерики и передать лямбда-функции для создания из этого многоразовой подпрограммы:

string[] arrayOfQueryTerms = getsTheArray();

var somequery = from q in dataContext.MyTable
                select q;

if (arrayOfQueryTerms.Length == 1)
{
    somequery = somequery.Where<MyTableEntity>(
        e => e.FieldName.StartsWith(arrayOfQueryTerms[0]));
}
else
{
    foreach(string queryTerm in arrayOfQueryTerms)
    {
        if (!String.IsNullOrEmpty(queryTerm))
        {
            somequery = somequery 
                        .Where<MyTableEntity>(
                            e => e.FieldName.Contains(queryTerm));
        }
    }
}

Я надеялся создать универсальный метод с сигнатурой, который будет выглядеть примерно так:

private IQueryable<T> getQuery(
    T MyTableEntity, string[] arrayOfQueryTerms, Func<T, bool> predicate)

Я использую одну и ту же стратегию поиска по всем моим таблицам, поэтому единственное, что действительно отличается от использования к использованию, - это поиск MyTable & MyTableEntity и поиск FieldName. Имеет ли это смысл? Есть ли способ с помощью LINQ динамически передавать имя поля для запроса в предложении where? Или я могу передать это как предикат лямбда?

e => e.FieldName.Contains(queryTerm)

Я понимаю, что существует полтора с половиной способа сделать это в SQL, возможно, проще, но я бы хотел оставить все в семействе LINQ для этого. Кроме того, я чувствую, что генерики должны быть полезны для такой проблемы, как эта. Есть идеи?

Ответы [ 4 ]

15 голосов
/ 24 сентября 2008

Звучит так, будто вы ищете Dynamic Linq. Взгляните здесь . Это позволяет передавать строки в качестве аргументов в методы запроса, например:

var query = dataSource.Where("CategoryID == 2 && UnitPrice > 3")
                      .OrderBy("SupplierID");

Редактировать: еще один набор сообщений на эту тему с использованием динамической поддержки C # 4: Часть 1 и Часть 2 .

7 голосов
/ 24 сентября 2008

Как это звучит, так это то, что вы хотите в основном конструктор условных предикатов ..

Я надеюсь, что вы можете превратить это в то, что вы ищете, удачи!

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

6 голосов
/ 24 сентября 2008

Вы можете посмотреть на деревья выражений:

IQueryable<T> getQuery<T>(T myTableEntity, string[] arrayOfQueryTerms, Expression<Func<T, bool>> predicate)
 { var fieldOrProperty = getMemberInfo(predicate);
   /* ... */
 }

MemberInfo getmemberInfo<T>(Expression<Func<T,bool> expr)
 { var memberExpr = expr as MemberExpression;
   if (memberExpr != null) return memberExpr.Member;
   throw new ArgumentException();
 }

var q = getQuery<FooTable>(foo, new[]{"Bar","Baz"}, x=>x.FieldName);
0 голосов
/ 09 ноября 2008

Мне недавно пришлось сделать то же самое. Вам понадобится Dynamic Linq , здесь - способ сохранить это строго типизированным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...