From 4f29627a67475d790a941e728c678579cd2913a7 Mon Sep 17 00:00:00 2001 From: Phil Boyd Date: Mon, 1 Aug 2016 22:12:02 -0400 Subject: [PATCH] Issue #1 - modified GetModelParametersForModelDefinedFunction to take into account parameters can be different EdmTypes --- .../Examples/ModelDefinedFunctions.cs | 24 ++++++--- .../UnitTests/FunctionTests.cs | 12 +++++ EntityFramework.Functions/Function.DbModel.cs | 52 ++++++++++++++----- 3 files changed, 68 insertions(+), 20 deletions(-) diff --git a/EntityFramework.Functions.Tests/Examples/ModelDefinedFunctions.cs b/EntityFramework.Functions.Tests/Examples/ModelDefinedFunctions.cs index 0d41739..f912c85 100644 --- a/EntityFramework.Functions.Tests/Examples/ModelDefinedFunctions.cs +++ b/EntityFramework.Functions.Tests/Examples/ModelDefinedFunctions.cs @@ -3,14 +3,26 @@ using EntityFramework.Functions.Tests.Library.Examples; public static class ModelDefinedFunctions - { - [ModelDefinedFunction(nameof(FormatName), "EntityFramework.Functions.Tests.Examples", + { + [ModelDefinedFunction(nameof(FormatName), "EntityFramework.Functions.Tests.Examples", @"(CASE WHEN [Person].[Title] IS NOT NULL THEN [Person].[Title] + N' ' ELSE N'' END) + [Person].[FirstName] + N' ' + [Person].[LastName]")] - public static string FormatName(this Person person) => - $"{(person.Title == null ? string.Empty : person.Title + " ")}{person.FirstName} {person.LastName}"; - } -} \ No newline at end of file + public static string FormatName(this Person person) => + $"{(person.Title == null ? string.Empty : person.Title + " ")}{person.FirstName} {person.LastName}"; + + /* + + + + cast(svalue as Edm.Double) + + + */ + [ModelDefinedFunction(nameof(ParseDouble), "EntityFramework.Functions.Tests.Examples", @"cast(svalue as Edm.Double)")] + public static double ParseDouble(this string svalue) => double.Parse(svalue); + + } +} diff --git a/EntityFramework.Functions.Tests/UnitTests/FunctionTests.cs b/EntityFramework.Functions.Tests/UnitTests/FunctionTests.cs index 5bd424c..be6dafe 100644 --- a/EntityFramework.Functions.Tests/UnitTests/FunctionTests.cs +++ b/EntityFramework.Functions.Tests/UnitTests/FunctionTests.cs @@ -235,5 +235,17 @@ public void ModelDefinedFunctionInLinqTest() Assert.AreEqual(employeeData.employee.FormatName(), employeeData.formatted); } } + + [TestMethod] + public void ModelDefinedFunctionInLinqTest2() + { + using (AdventureWorks database = new AdventureWorks()) + { + var result = (from employee in database.Persons + let formatted = "23.00".ParseDouble() + select formatted).FirstOrDefault(); + Assert.AreEqual(23.00, result); + } + } } } diff --git a/EntityFramework.Functions/Function.DbModel.cs b/EntityFramework.Functions/Function.DbModel.cs index 100ce0d..8f027ad 100644 --- a/EntityFramework.Functions/Function.DbModel.cs +++ b/EntityFramework.Functions/Function.DbModel.cs @@ -492,7 +492,7 @@ private static IList GetStoreReturnParameters( if (modelReturnParameterComplexType != null) { storeReturnParameterRowType = RowType.Create( - modelReturnParameterComplexType.Properties.Select(property => + modelReturnParameterComplexType.Properties.Select(property => EdmProperty.Create(property.Name, model.ProviderManifest.GetStoreType(property.TypeUsage))), null); } @@ -557,12 +557,34 @@ private static IList GetModelParametersForModelDefinedFunctio this DbModel model, MethodInfo methodInfo) { ParameterInfo[] parameters = methodInfo.GetParameters().ToArray(); - return parameters - .Select((parameterInfo) => FunctionParameter.Create( - parameterInfo.GetCustomAttribute()?.Name ?? parameterInfo.Name, - model.GetModelStructualType(parameterInfo.ParameterType, methodInfo), - ParameterMode.In)) - .ToArray(); + return parameters.Select( + (parameterInfo) => + { + EdmType type = model.GetModelPrimitiveType(parameterInfo.ParameterType, methodInfo); + if (type == null) + { + type = model.GetModelComplexType(parameterInfo.ParameterType, methodInfo); + if (type == null) + { + type = model.GetModelEntityType(parameterInfo.ParameterType, methodInfo); + if (type == null) + { + type = model.GetModelStructualType(parameterInfo.ParameterType, methodInfo); + if (type == null) + { + throw new NotSupportedException( + $"{parameterInfo.ParameterType.FullName} for method {methodInfo.Name} is " + + "not supported in conceptual model"); + } + } + } + } + + return FunctionParameter.Create(parameterInfo.GetCustomAttribute()?.Name ?? parameterInfo.Name, + type, + ParameterMode.In); + } + ).ToArray(); } private static IList GetModelReturnParameters( @@ -694,11 +716,11 @@ private static PrimitiveType GetModelPrimitiveType(this DbModel model, Type clrT PrimitiveType modelPrimitiveType = PrimitiveType .GetEdmPrimitiveTypes() .FirstOrDefault(primitiveType => primitiveType.ClrEquivalentType == clrType); - if (modelPrimitiveType == null) - { - throw new NotSupportedException( - $"Type {nameof(clrType.FullName)} in method {methodInfo.Name} is not supported in conceptual model."); - } + //if (modelPrimitiveType == null) + //{ + // throw new NotSupportedException( + // $"Type {nameof(clrType.FullName)} in method {methodInfo.Name} is not supported in conceptual model."); + //} return modelPrimitiveType; } @@ -717,8 +739,10 @@ private static StructuralType GetModelStructualType(this DbModel model, Type clr return complexType; } - throw new NotSupportedException( - $"{clrType.FullName} for method {methodInfo.Name} is not supported in conceptual model as a structural type."); + return default(StructuralType); + + //throw new NotSupportedException( + // $"{clrType.FullName} for method {methodInfo.Name} is not supported in conceptual model as a structural type."); } private static EntityType GetModelEntityType(this DbModel model, Type clrType, MethodInfo methodInfo)