I am trying to write additional EF.Functions that must be executed on the server.
This works well if at least one of the function arguments is a reference to a database column. (via the entity model)
If all arguments are constants, or if there are no arguments, it results in an exception.
This exception occurs without our custom IMethodCallTranslator code getting called.
Linq (?) apparently decides that if there are no object references then it can process the expression locally ... which of course it can not.
The second exception message, below, is from the exception we throw when you try to evaluate one of our extension functions locally.
The stack trace seems to indicate that the problem occurs when initially building the Linq expression tree - before the 'Relational' layer gets a chance to look at it.
Exception:
System.InvalidOperationException : An exception was thrown while attempting to evaluate a LINQ query parameter expression.
----> System.InvalidOperationException : Teradata Database specific functions can not be evaluated on the client.
Stack trace:
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.Evaluate(Expression expression, String& parameterName)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.TryExtractParameter(Expression expression)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection1 nodes) at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.VisitNew(NewExpression node) at System.Linq.Expressions.NewExpression.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression1 node)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.VisitLambda[T](Expression1 node) at System.Linq.Expressions.Expression1.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.VisitUnary(UnaryExpression unaryExpression)
at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.ExtractParameters(Expression expression)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Remotion.Linq.QueryableBase1.GetEnumerator() at System.Collections.Generic.List1.AddEnumerable(IEnumerable1 enumerable) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source)
at Teradata.EntityFrameworkCore.Tests.TeradataQueryTeradataFunctionTests.NumericTests() in C:\AppSourceCurrent\TdNetDp\Tests\EntityFramework\EFCore.Teradata.Tests\TeradataQueryTeradataFunctionTests.cs:line 142
--InvalidOperationException
at Teradata.EntityFrameworkCore.TeradataDbFunctionsExtensions.Random(DbFunctions _, Int32 lowerBound, Int32 upperBound) in C:\AppSourceCurrent\TdNetDp\src\TdDotNetDataProvider\EFCore.Teradata\Extensions\TeradataDbFunctionsExtensions.cs:line 46
at lambda_method(Closure )
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.Evaluate(Expression expression, String& parameterName)
Steps to reproduce
Can not be reproduced without an Entity Provider that implements EF.Functions of this type.
Example 1
The function RANDOM(1, 256) should generate a random number between 1 and 256 for each row in the result set. (This random number will generally be used in an expression, but may sometimes need to be returned in the result set.)
Example 2
The function CurrentUser() should return the user name of the user that connected the database session.
Further technical details
EF Core version: 2.1
Database Provider: Teradata.EntityFrameworkCore
Operating system: Windows 10
IDE: Visual Studio 2017 15.7.2
I am trying to write additional EF.Functions that must be executed on the server.
This works well if at least one of the function arguments is a reference to a database column. (via the entity model)
If all arguments are constants, or if there are no arguments, it results in an exception.
This exception occurs without our custom IMethodCallTranslator code getting called.
Linq (?) apparently decides that if there are no object references then it can process the expression locally ... which of course it can not.
The second exception message, below, is from the exception we throw when you try to evaluate one of our extension functions locally.
The stack trace seems to indicate that the problem occurs when initially building the Linq expression tree - before the 'Relational' layer gets a chance to look at it.
Exception:
System.InvalidOperationException : An exception was thrown while attempting to evaluate a LINQ query parameter expression.
----> System.InvalidOperationException : Teradata Database specific functions can not be evaluated on the client.
Stack trace:
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.Evaluate(Expression expression, String& parameterName)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.TryExtractParameter(Expression expression)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection
1 nodes) at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.VisitNew(NewExpression node) at System.Linq.Expressions.NewExpression.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at System.Linq.Expressions.ExpressionVisitor.VisitLambda[T](Expression1 node)at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.VisitLambda[T](Expression
1 node) at System.Linq.Expressions.Expression1.Accept(ExpressionVisitor visitor)at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.VisitUnary(UnaryExpression unaryExpression)
at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.ExtractParameters(Expression expression)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Remotion.Linq.QueryableBase
1.GetEnumerator() at System.Collections.Generic.List1.AddEnumerable(IEnumerable1 enumerable) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source)at Teradata.EntityFrameworkCore.Tests.TeradataQueryTeradataFunctionTests.NumericTests() in C:\AppSourceCurrent\TdNetDp\Tests\EntityFramework\EFCore.Teradata.Tests\TeradataQueryTeradataFunctionTests.cs:line 142
--InvalidOperationException
at Teradata.EntityFrameworkCore.TeradataDbFunctionsExtensions.Random(DbFunctions _, Int32 lowerBound, Int32 upperBound) in C:\AppSourceCurrent\TdNetDp\src\TdDotNetDataProvider\EFCore.Teradata\Extensions\TeradataDbFunctionsExtensions.cs:line 46
at lambda_method(Closure )
at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor.Evaluate(Expression expression, String& parameterName)
Steps to reproduce
Can not be reproduced without an Entity Provider that implements EF.Functions of this type.
Example 1
The function RANDOM(1, 256) should generate a random number between 1 and 256 for each row in the result set. (This random number will generally be used in an expression, but may sometimes need to be returned in the result set.)
Example 2
The function CurrentUser() should return the user name of the user that connected the database session.
Further technical details
EF Core version: 2.1
Database Provider: Teradata.EntityFrameworkCore
Operating system: Windows 10
IDE: Visual Studio 2017 15.7.2