Конвертировать строку в Int в EF 4.0 - PullRequest
20 голосов
/ 22 апреля 2011

Есть ли способ сделать это вообще? У меня есть строковое поле в БД, и я хочу проанализировать его в свойстве int в моем запросе LINQ (да, оно должно быть на уровне IQueryable, а не в памяти).

Я знаю, что 2 года назад EF 1.0 не мог этого сделать (хотя LINQ to SQL поддерживал эту базовую функциональность из коробки) ... но мне просто интересно, придумал ли кто-нибудь способ сделать это с этой точки зрения?

Пользовательские сопоставления функций? Специальный синтаксис? Все что угодно ....

UPDATE:

Я попробовал функцию, определенную моделью, следующим образом:

    <Function Name="ConvertToInt32" ReturnType="Edm.Int32">
      <Parameter Name="v" Type="Edm.String" />
      <DefiningExpression>
        CAST(v AS INT)
      </DefiningExpression>
    </Function>

    [EdmFunction("Model.Repository", "ConvertToInt32")]
    public static int ConvertToInt32(string value)
    {
        throw new InvalidOperationException("Only valid when used as part of a LINQ query.");
    }

но это не похоже на работу. Я получаю исключение времени выполнения:

        ErrorDescription=Type 'INT' could not be found. Make sure that the required schemas are loaded and that the namespaces are imported correctly.
        StackTrace:
             at System.Data.Common.EntitySql.SemanticAnalyzer.ConvertTypeName(Node typeName, SemanticResolver sr)
             at System.Data.Common.EntitySql.SemanticAnalyzer.ConvertTypeExprArgs(BuiltInExpr astBuiltInExpr, SemanticResolver sr)
             at System.Data.Common.EntitySql.SemanticAnalyzer.<CreateBuiltInExprConverter>b__73(BuiltInExpr bltInExpr, SemanticResolver sr)
             at System.Data.Common.EntitySql.SemanticAnalyzer.ConvertBuiltIn(Node astExpr, SemanticResolver sr)
             at System.Data.Common.EntitySql.SemanticAnalyzer.Convert(Node astExpr, SemanticResolver sr)
             at System.Data.Common.EntitySql.SemanticAnalyzer.ConvertValueExpression(Node astExpr, SemanticResolver sr)
             at System.Data.Common.EntitySql.SemanticAnalyzer.ConvertQueryStatementToDbExpression(Statement astStatement, SemanticResolver sr)
             at System.Data.Common.EntitySql.SemanticAnalyzer.AnalyzeQueryCommand(Node astExpr)
             at System.Data.Common.EntitySql.CqlQuery.<AnalyzeQueryExpressionSemantics>b__8(SemanticAnalyzer analyzer, Node astExpr)
             at System.Data.Common.EntitySql.CqlQuery.AnalyzeSemanticsCommon[TResult](Node astExpr, Perspective perspective, ParserOptions parserOptions, IEnumerable`1 parameters, IEnumerable`1 variables, Func`3 analysisFunction)
             at System.Data.Common.EntitySql.CqlQuery.AnalyzeQueryExpressionSemantics(Node astQueryCommand, Perspective perspective, ParserOptions parserOptions, IEnumerable`1 parameters, IEnumerable`1 variables)
             at System.Data.Common.EntitySql.CqlQuery.<>c__DisplayClass4.<CompileQueryCommandLambda>b__3(Node astCommand, ParserOptions validatedParserOptions)
             at System.Data.Common.EntitySql.CqlQuery.CompileCommon[TResult](String commandText, Perspective perspective, ParserOptions parserOptions, Func`3 compilationFunction)
             at System.Data.Common.EntitySql.CqlQuery.CompileQueryCommandLambda(String queryCommandText, Perspective perspective, ParserOptions parserOptions, IEnumerable`1 parameters, IEnumerable`1 variables)
             at System.Data.Mapping.ViewGeneration.Utils.ExternalCalls.CompileFunctionDefinition(String functionFullName, String functionDefinition, IList`1 functionParameters, EdmItemCollection edmItemCollection)
             at System.Data.Metadata.Edm.EdmItemCollection.GenerateFunctionDefinition(EdmFunction function)
             at System.Data.Common.Utils.Memoizer`2.<>c__DisplayClass2.<Evaluate>b__0()
             at System.Data.Common.Utils.Memoizer`2.Result.GetValue()
             at System.Data.Common.Utils.Memoizer`2.Evaluate(TArg arg)
             at System.Data.Metadata.Edm.EdmItemCollection.GetGeneratedFunctionDefinition(EdmFunction function)
             at System.Data.Metadata.Edm.MetadataWorkspace.GetGeneratedFunctionDefinition(EdmFunction function)
             at System.Data.Query.PlanCompiler.ITreeGenerator.Visit(DbFunctionExpression e)
        InnerException: 

ОБНОВЛЕНИЕ: Я получил его на работу следующим образом

 <Function Name="ConvertToInt32" ReturnType="Edm.Int32">
      <Parameter Name="v" Type="Edm.String" />
      <DefiningExpression>
        CAST(v AS Edm.Int32)
      </DefiningExpression>
    </Function>

1 Ответ

13 голосов
/ 22 апреля 2011

Если вы используете EFv4 + EDMX, вы можете создать пользовательскую функцию, определенную моделью , которая сделает CAST для вас.Затем вы можете использовать эту функцию в запросах Linq-to-entity.

...