У меня есть таблица со столбцом типа 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, если ничего другого не существует.
Закончилось понтирование.
Кажется, что Entity Framework, думая, что работает только с объектами, хочет всегда проводить строгую проверку типов, в то же время не имеет механизма для преобразования между типами для целей сравнения в SQL.
CONVERT( "1234", UNSIGNED )
, что даже CONVERT( "1234", UNSIGNED )
, предоставляемый MySQL, не может быть закодирован, а тем более решениями с Int64.Parse()
.
Закончился доступ к сырому SQL через MySqlConnection
/ MySqlCommand
/ MySqlDataReader
.
Вы можете использовать «Конвертировать», поставщик может перевести это.
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)