Преобразование строки в Long ... в LINQ to Entity Framework с использованием адаптера MySQL - PullRequest
1 голос
/ 24 февраля 2010

У меня есть таблица со столбцом типа varchar, где большинство строк имеют числовые значения, то есть каждая строка содержит только цифры от 0 до 9.

+------+
|  n   |
+------+
| 123  |
| 234  |
| BLAH |  -- This row is an exception to the rule.
| 456  |
| 789  |
+------+

В MySQL это работает: SELECT * FROM t WHERE n >= 200 AND n <= 500;
возвращая строки, где n имеет значение 234, а также 456 для данных выше.

Я бы хотел использовать LINQ с Entity Framework, чтобы сделать то же самое.

var results = from n in context.t  
              let n_asLong = long.Parse(n)  // ...I know, see note below...
              where ( n != null && n_asLong >= lowVal && n_asLong <= hiVal )
              select n_asLong;

ПРИМЕЧАНИЕ. Да, я знаю, что long.Parse() сгенерирует исключение при получении недопустимого числа. На данный момент мои фактические данные содержат только юридически разбираемые строки. Я включил нечисловой элемент в надежде на полный, всеобъемлющий ответ.

Запуск этого кода приводит к исключению, относящемуся к кодировке LINQ:
LINQ to Entities не распознает метод Int64 Parse (Системная строка), и этот метод не может быть преобразован в выражение хранилища.

Я понимаю, почему он хочет выполнить преобразование в SQL.

Фактически, я провел эксперимент с MS-SQL, и мне пришлось экспортировать пользовательскую функцию со строкой в ​​длину, которая распознавала неверные данные (возвращая 0 для нечисловых значений, таких как «BLAH»), и которая работала с LINQ to SQL, хотя это был гораздо более сложный обходной путь, чем хотелось бы.

Как оказалось, я заблокирован решением MySQL. Так что вышеупомянутый хак для конкретного поставщика не будет работать.

Я не могу не думать о том, что имеет для способа обработки строки как значения (как позволяет даже собственный SQL) и для LINQ to Entity Frameworks.

Какие-нибудь хорошие подходы от некоторых экспертов по базам данных / C # / .NET / LINQ?

Если необходимо, я готов воспользоваться позорным решением execute-raw-SQL-direct, если ничего другого не существует.

Ответы [ 2 ]

3 голосов
/ 07 июля 2010

Вы можете использовать «Конвертировать», поставщик может перевести это.

var results = from n in context.t  
              let n_asLong = Convert.ToInt64(n) // -- Here is the magic
              where ( n != null && n_asLong >= lowVal && n_asLong <= hiVal )
              select n_asLong;

(по крайней мере, у меня сработало использование SQL Server express и LINQPad)

1 голос
/ 01 марта 2010

Закончилось понтирование.

Кажется, что Entity Framework, думая, что работает только с объектами, хочет всегда проводить строгую проверку типов, в то же время не имеет механизма для преобразования между типами для целей сравнения в SQL.

Шокирующе, даже CONVERT( "1234", UNSIGNED ), который предоставляет MySQL, не может быть закодирован, тем более решения с Int64.Parse().

Закончен доступ к необработанному SQL через MySqlConnection / MySqlCommand / MySqlDataReader.

...