Entity Framework / Linq EXpression преобразует из строки в int

У меня есть выражение вроде так:

var values = Enumerable.Range(1,2);

return message => message.Properties.Any(
    p => p.Key == name 
    && int.Parse(p.Value) >= values[0] 
    && int.Parse(p.Value) = а также
 Marc Gravell22 мая 2013 г., 16:43
Есть лиConvert.ToInt32(p.Value) Работа?
 vcsjones22 мая 2013 г., 16:43
использованиеConvert.ToInt32 вместо. EF это понимает.
 Jon22 мая 2013 г., 16:44
Это нет, я попробовал это
 mattytommo22 мая 2013 г., 16:40
Isn»т, что красный флаг, что вашValue должен бытьint в вашей базе данных?
 Marc Gravell22 мая 2013 г., 16:41
ах, должен любитьэффект внутренней платформы "... создание таблицы базы данных (столбцы / строки) с использованием таблицы базы данных ...

Ответы на вопрос(4)

Недавно мне пришлось преобразовать строку (числовое представление) в значение перечисления в запросе LINQ без материализации запроса. Мое перечисление использовало значения int между 0 и 9, поэтому я сделал что-то вроде этого:

    .Select(str => (MyEnum?)(SqlFunctions.Unicode(str) - 48))

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

Решение Вопроса

При анализе этого значения должен быть красный флаг, который вы должны использовать в вашей базе данных другого типа.

К счастью, существует обходной путь, заставляющий запрос выполняться LINQ to Objects, а не LINQ to Entities. К сожалению, это означает, что возможно чтение большого объема данных в память

РЕДАКТИРОВАТЬ

Основываясь на других ваших комментариях, значение в столбце Значение ins 'т гарантированно будет число. Поэтому тыЯ должен попытаться преобразовать значение в число, а затем обработать вещи на основе неудачи / успеха этого преобразования:

return message
       .Properties
       .AsEnumerable()
       .Any(p => 
            {
                var val = 0;
                if(int.TryParse(p.Value, out val))
                {
                    return p.Key == name &&
                           val >= values[0] &&
                           val <= values[1])
                }
                else
                {
                    return false;
                }
           );

РЕДАКТИРОВАТЬ 2

Возможно, вам действительно удастся избежать этого в базе данных. Я'Я не уверен, сработает ли это для вас или нет, но попробуйте:

return message.Properties
              .Where(p => p.Key == name && SqlFunctions.IsNumeric(p.Value) > 0)
              .Any(p => Convert.ToInt32(p.Value) >= values[0] &&
                        Convert.ToInt32(p.Value) <= values[1]);
 Jon22 мая 2013 г., 17:33
м, используя Code First
 Jon22 мая 2013 г., 17:18
думаю, мне придется купировать изменения схемы БД
 Justin Niessner22 мая 2013 г., 17:19
@Jon - Вы используете EDMX или Code-First для EF?
 Jon22 мая 2013 г., 16:49
Я пытаюсь этого не делать, так как это часть метода фильтрации, который должен попасть в БД и вернуть отфильтрованные данные таким образом.
 Justin Niessner22 мая 2013 г., 16:52
@Jon - Так как данные нет обязательно должен быть номер, тамНет хорошего способа обработать преобразование в базе данных. Вы можете использовать код, аналогичный приведенному выше, или использовать строки для сравнения.
 Justin Niessner22 мая 2013 г., 17:03
@Jon - Только что добавил еще один возможный вариант для вас. Я'я не уверен на 100%Я буду работать в вашем случае, но если это произойдет,Позволит вам правильно использовать Convert.ToInt32.
 Jon22 мая 2013 г., 16:56
как я могу использовать строки для сравнения, используя операторы больше / меньше, чем
 Jon22 мая 2013 г., 17:09
задница, я получаю LINQ to Entities не распознает метод 'Int32 ToInt32 (System.String) ' метод, и этот метод не может быть преобразован в выражение хранилища.
 Jon22 мая 2013 г., 17:07
попробует написать TSQL, даже с подзапросом, но он не будет правильно фильтровать

Convert.ToInt32(input); Если вы не уверены, вы можетеTryParse, Это не будет выдавать исключение, но false не может разобрать. НоConvert.ToInt32(input); должно сработать. Вы можете прочитать об этом наhttp://msdn.microsoft.com/en-us/library/vstudio/bb397679.aspx.

 Eren Ersönmez22 мая 2013 г., 16:51
вы не можете использоватьTryParse в выражении EF запроса.
 user239976022 мая 2013 г., 16:56
Didn»У меня не было возможности проверить это сразу, но спасибо вам за это! Думал, что это может сработать.

Столько, сколько я ненавижу этот ответ. Фактический ответ: вы не можете сделать это легко. Это будет настоящая боль. Я'Мы видели много неправильных ответов и множество ответов, когда люди говорили, что вы должны просто указывать правильные поля в вашей базе данных. не полезно.

Этот вопрос похож наhttp://social.msdn.microsoft.com/Forums/en-US/ce9652e3-5450-44c4-a9bd-586b4c4e6a27/convert-string-to-int-in-whereorderby-is-it-possible?forum=adodotnetentityframework

Есть несколько возможностей в зависимости от того, какой тип EF вы используете.

1. Вы используете файлы EDMX.

(Не кодируйте сначала или сначала измените код). Вы можете использовать что-то вроде (LINQ to Entities не распознает метод »Двойной анализ (System.String) ' метод, и этот метод не может быть переведен в выражение магазина)

 [EdmFunction("PlusDomain", "ParseDouble")]
    public static double ParseDouble(string stringvalue)
    {
        ///     This method exists for use in LINQ queries,
        ///     as a stub that will be converted to a SQL CAST statement.
        return System.Double.Parse(stringvalue);
    }

и карта в вашем EDMX

>  
>       
>       
>         cast(stringvalue as Edm.Double)
>       
>     
2. Если вы используете код сначала в EF>= 4.1.

Вы облажались Microsoft не сделалСчитаю целесообразным добавить любую такую функцию в SqlFunctions. Лучшее, на что вы можете надеяться, - это добавить скалярную функцию SQL в вашу базу данных и (возможно) попытаться отобразить ее в своем контексте. Microsoft не сделалЯ не вижу смысла делать что-то подобное в коде первым. К счастью, они неТочно блокировать такие вещи тоже. Свободный API является мощным.

Это'будет что-то вроде этого:

Вы можете вызывать функции или хранимые процедуры следующим образом:определить скалярную функцию с кодом ef4.1 первым? или жеhttp://weblogs.asp.net/dwahlin/using-entity-framework-code-first-with-stored-procedures-that-have-output-parameters лайк:

var outParam = новый SqlParameter ("сверхурочная работа», SqlDbType.Int); outParam.Direction = ParameterDirection.Output;

var data = context.Database.ExecuteSqlCommand ("dbo.sp_getNumberJobs @overHours OUT ", outParam); int numJobs = (int) outParam.Value;

но чтобы они действительно интегрировались в LinQ для сущностей, вам нужно что-то вроде этого:

https://codefirstfunctions.codeplex.com/ с помощьюhttp://www.nuget.org/packages/EntityFramework.CodeFirstStoreFunctions он отображает функции SQL в контекст, но при этом используется внешняя библиотека, созданная только для .NET 4.5http://blog.3d-logic.com/2014/04/09/support-for-store-functions-tvfs-and-stored-procs-in-entity-framework-6-1/

или Вы можете попытаться сделать то же самое вручную, например:

Entity Framework 6 Code First отображение функций или же

https://entityframework.codeplex.com/discussions/494365

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

 Alexandru Clonțea28 апр. 2018 г., 01:42
Я знаю, что это старый ответ, но он действительно помог мне открыть глаза на недавний выпуск. Ответ хороший, но есть также способ использовать функции, определяемые моделью, с кодом в первую очередь! Хотя это немного больше работы. Увидетьstackoverflow.com/questions/29503962/...  Кроме того, код MS, кажется, выбрасывает NotImplementedException ("не для прямых звонков) в самом коде C #, и я думаю, что это разумно. Этот вызов предназначен для перевода из дерева выражений в реальный SQL, а не для непосредственного вызова!

Ваш ответ на вопрос