Проблема в том, что ваш запрос переводится в SQL и выполняется в базе данных, а Entity Framework не знает, как перевести Double.Parse
в действительный код SQL. Однако вы можете определить пользовательский метод для анализа и указать Entity Framework, как преобразовать этот метод в SQL. Вот как это происходит:
Определить перевод
Откройте файл * .edmx в текстовом редакторе и найдите тег <edmx:ConceptualModels>
. Под этим вы должны увидеть тег <Schema Namespace="YourModel" ...>
. Внутри тега схемы добавьте следующее:
<Function Name="ParseDouble" ReturnType="Edm.Double">
<Parameter Name="stringvalue" Type="Edm.String" />
<DefiningExpression>
cast(stringvalue as Edm.Double)
</DefiningExpression>
</Function>
Это определяет код Enity-SQL, в который будет преобразована ваша пользовательская функция ParseDouble.
Создать метод для перевода
Теперь нам нужно определить соответствующую функцию в коде, которую вы можете вставить в оператор LINQ. Ваш файл EDMX используется для генерации частичного класса, который наследуется от ObjectContext. Поскольку это частичный класс, вы можете добавлять в него свои собственные методы, не касаясь сгенерированного кода - просто убедитесь, что имена классов совпадают.
using System.Data.Objects.DataClasses;
public partial class YourObjectContext
{
/// <summary>
/// This method exists for use in LINQ queries,
/// as a stub that will be converted to a SQL CAST statement.
/// </summary>
[EdmFunction("YourModel", "ParseDouble")]
public static double ParseDouble(string stringvalue)
{
return Double.Parse(stringvalue);
}
}
Теперь вы можете вернуться к своему выражению LINQ и заменить любые экземпляры Double.Parse
на YourObjectContext.ParseDouble
. Поскольку это фактический метод, который на самом деле вызывает Double.Parse
, он будет работать при вызовах LINQ to Objects, и поскольку он также определен в файле EDMX, его также можно преобразовать в SQL с помощью LINQ to Entities.
Но подождите, вы еще не закончили!
Я заметил, что ваш оператор LINQ также включает вызов Math.Round
. Я не знаю, во что бы то ни стало, если Entity Framework включает перевод для этого метода, но если этого не произойдет, вы получите ту же ошибку для этого метода после исправления ошибки для Double.Parse
. К счастью, решение для этого случая почти такое же, за исключением того, что функция, определенная в файле EDMX, будет выглядеть примерно так:
<Function Name="Round" ReturnType="Edm.Double">
<Parameter Name="input" Type="Edm.Double" />
<DefiningExpression>
Round(input)
</DefiningExpression>
</Function>
Вы можете использовать этот список Канонических функций EDM , чтобы увидеть, что можно поместить в теги <DefiningExpression>
.