NHibernate Linq: как использовать StartsWith на целочисленном типе - PullRequest
2 голосов
/ 17 февраля 2011

Я бы хотел выполнить такой запрос, но он не прошел:

session.Linq<Product>().Where(p=>p.Id.ToString().StartsWith("123"))

Есть ли обходной путь?Я предпочел бы использовать LINQ ... может быть, есть простой способ расширить провайдера linq?

Я использую NHibernate 2.1.2

РЕДАКТИРОВАТЬ: Да, это не удается, потому что NHIbernate.Linq не обрабатывает ToString ()

Ответы [ 4 ]

3 голосов
/ 17 февраля 2011

Я согласен с SLaks в комментариях, что если вам нужно сравнение строк в поле идентификатора продукта, то это должно быть поле char или varchar для начала.

Является ли количество цифр в идентификаторе продукта постоянным?В этом случае вы могли бы написать что-то вроде:

session.Linq<Product>().Where(p=>p.Id >= 10000 && p.Id < 20000)

Даже если вы не знаете количество цифр, вы можете написать

session.Linq<Product>().Where(p=> 
    (p.Id >= 10 && p.Id < 20) || 
    (p.Id >= 100 && p.Id < 200) || 
    (p.Id >= 1000 && p.Id < 2000) || 
    (p.Id >= 10000 && p.Id < 20000) || ... );

Ну, это уродливо, но это будетработа: -)

Кстати, вы можете получить первую цифру в T-SQL, используя следующее выражение:

(Product.Id / POWER(10, FLOOR(LOG10(Product.Id))))

Однако я не думаю, что поставщик Linq дляNHibernate 2.1.2 может отображать математические функции .Net в соответствующие функции T-SQL.Вы можете попробовать:

session.Linq<Product>().Where(p => p.Id / Math.Pow(10, Math.Floor(Math.Log10(p.Id))) == 1)
2 голосов
/ 17 февраля 2011

Если вы обновитесь до NHibernate 3, вы можете расширить поставщика LINQ , чтобы он распознавал выражение типа p.Id.NumberStartsWith(1) (это обернет любой из предложенных подходов как ответы на этот вопрос)

Это немного работы, но как только это будет сделано, клиентский код будет выглядеть довольно хорошо.

Плюс, вам будет очень весело: -)

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

Если вам абсолютно необходимо это сделать, вам может потребоваться создать параллельный столбец, который может быть строковой версией вашего ключа. Использование перехватчиков NHibernate, триггера базы данных или множества других опций будет обновлять поле и синхронизировать его, не портя код.

Думаю, я бы избегал этого, но это один из способов, которым вы могли бы пойти.

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

Скорее всего, запрос не будет выполнен, потому что NHibernate не знает, как преобразовать ToString () (или различные синтаксические разборы) в методы CAST / CONVERT.

Я согласен с Elian и SLaks - если вам нужен один «символ» из идентификатора продукта, этот идентификатор должен быть varchar. Нет действительно элегантного способа заставить этот запрос работать иначе; если бы это была строка, функция StartsWith () была бы преобразована в состояние ProductId LIKE 'x%' без особых усилий.

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