EntityFramework.Functions library implements Entity Framework code first support for stored procedures (with single result type, multiple result types, output parameter), table-valued functions (returning entity type, complex type), scalar-valued functions (composable, non-composable), aggregate functions, built-in functions, niladic functions, and model defined functions.
Attempting to call a TVF from within a LINQ query results in an exception:
System.NotSupportedException: The specified method
'System.Linq.IQueryable`1[EntityFramework.Functions.Tests.Examples.ContactInformation] ufnGetContactInformation(System.Nullable`1[System.Int32])'
on the type 'EntityFramework.Functions.Tests.Examples.AdventureWorks' cannot
be translated into a LINQ to Entities store expression because its return
type does not match the return type of the function specified by its DbFunction attribute.
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.FunctionCallTranslator.ValidateReturnType(DbExpression result, TypeUsage actualReturnType, ExpressionConverter parent, MethodCallExpression call, Type clrReturnType, Boolean isElementOfCollection)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.FunctionCallTranslator.ValidateReturnType(DbExpression result, TypeUsage actualReturnType, ExpressionConverter parent, MethodCallExpression call, Type clrReturnType, Boolean isElementOfCollection)
at System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.MethodCallTranslator.FunctionCallTranslator.TranslateFunctionCall(ExpressionConverter parent, MethodCallExpression call, DbFunctionAttribute functionAttribute)
The problem is that FunctionCallTranslator.TranslateFunctionCall looks up the function using the DbFunctionAttribute.NamespaceName property to get the namespace, but since the namespace is set to "CodeFirstDatabaseSchema" rather than the entity container name the function can't be found in CSpace and it gets looked up in SSpace instead (in Perspective.TryGetFunctionByName). The SSpace version of the function has the wrong return type, so FunctionCallTranslator.ValidateReturnType fails.
One fix is to change the constructor for EntityFramework.Functions.FunctionAttribute to something like
and add documentation that the namespaceName parameter should only be set for TVF imports. That's a little smelly though. I've put together a small change that adds specific attributes for each FunctionType to make things a little more clear. I'll submit a pull request for that, but maybe you can figure out away to make everything work correctly without adding anything to the API. I did some experimentation in Function.AddFunction but I couldn't figure out anything that worked.
Attempting to call a TVF from within a LINQ query results in an exception:
The problem is that
FunctionCallTranslator.TranslateFunctionCall
looks up the function using theDbFunctionAttribute.NamespaceName
property to get the namespace, but since the namespace is set to"CodeFirstDatabaseSchema"
rather than the entity container name the function can't be found in CSpace and it gets looked up in SSpace instead (inPerspective.TryGetFunctionByName
). The SSpace version of the function has the wrong return type, soFunctionCallTranslator.ValidateReturnType
fails.One fix is to change the constructor for
EntityFramework.Functions.FunctionAttribute
to something likeand add documentation that the
namespaceName
parameter should only be set for TVF imports. That's a little smelly though. I've put together a small change that adds specific attributes for eachFunctionType
to make things a little more clear. I'll submit a pull request for that, but maybe you can figure out away to make everything work correctly without adding anything to the API. I did some experimentation inFunction.AddFunction
but I couldn't figure out anything that worked.