Переводить этот запрос в LINQ? (список лайков) - PullRequest
0 голосов
/ 04 февраля 2011

Я бы хотел перевести этот запрос в LINQ ... его очень легко построить, если мы сделаем это на чистом SQL, но в динамически созданном запросе LINQ (построении поискового запроса на основе ввода пользователя) это совершенно новая история.

SELECT * FROM MyTable 
WHERE 1=1
  AND Column2 IN (1,2,3)
  AND ( Column1 LIKE '%a%' OR Column1 LIKE '%b%' )

Теперь, чтобы попытаться построить это, мы попробовали это так:

if(myOjb.Column2Collection != null)
    query = query.where(f => f.Column2.Contains(myOjb.Column2Collection));

if(myObj.Column1Collection != null)
{
    // tough part here ?
    //query = query.Where(); ...
}

Так, что было бы лучшим подходом к этому нормально?

Обратите внимание, что я знаю о SqlMethod.Как я не могу придумать способ реализовать это здесь ...

Ответы [ 5 ]

1 голос
/ 04 февраля 2011

Чтобы получить «Нравится» или «Нравится» и т. Д., Я думаю, вам нужно написать собственное расширение, чтобы построить дерево выражений для вас.Я хотел сделать это некоторое время назад и закончил тем, что нашел другую статью здесь на StackOverflow: Linq для Sql любого поискового запроса по ключевым словам

Оттуда, я думаю, вы напишите это:

string[] terms = new string[] {"a", "b"}
query = query.LikeAny(table => table.Column1, terms)

Кстати, вы также можете изменить код на связанной странице, чтобы сделать И вместо ИЛИ, изменив

var body = conditions.Aggregate((acc, c) => Expression.Or(acc, c));

на

var body = conditions.Aggregate((acc, c) => Expression.And(acc, c));

, что было то, что яхотел в то время, называя это LikeAll

0 голосов
/ 04 февраля 2011

Попробуйте это .

0 голосов
/ 04 февраля 2011
var sc = StringComparison.OrdinalIgnoreCase;
var col2Values = new int[] { 1, 2, 3 };    

var query = from item in myObj
            where col2Values.Contains(item.Column2)
            && (item.Column1.IndexOf("a", sc) >= 0
                || item.Column1.IndexOf("b", sc) >= 0)
            select item;

Я еще не проверял это, но он прекрасно работает.Исходная версия, если вышеперечисленное не работает:

var col2Values = new int[] { 1, 2, 3 };

var query = from item in myObj
            let col1 = item.Column1.ToLower()
            where col2Values.Contains(item.Column2)
            && (col1.Contains("a") || col1.Contains("b"))
            select item;

Я на самом деле предпочитаю вторую версию, даже если она немного медленнее из-за ToLower().На мой взгляд, легче читать.YMMV.

0 голосов
/ 04 февраля 2011
from o in myObj
where
new[] { 1, 2, 3 }.Contains(o.Column2) &&
new[] { "a", "b" }.Any(s => o.Column1.IndexOf(s, StringComparison.Ordinal) != -1)
select o;
<ч />

или используйте new Hashset<T>, если вам нужна производительность поиска. Массив приносит только O (n).

<ч />

Ordinal означает сравнение байтов за байтом в Юникоде без проблем, связанных с культурой, самое быстрое.

OrdinalIgnoreCase означает то же самое, но с учетом регистра

0 голосов
/ 04 февраля 2011

Попробуйте что-то вроде этого:

var colums2 = { 1, 2, 3 };
var result = (from o in myOjb
              where columns2.Any(co2 => co2 == o.Column2)
              && Column1.Contains(column2valueA)
              || Column1.Contains(column2valueB)
              select o);

Надежда может помочь

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