Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions EntityFramework.Functions.Tests/Examples/ModelDefinedFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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}";
}
}
public static string FormatName(this Person person) =>
$"{(person.Title == null ? string.Empty : person.Title + " ")}{person.FirstName} {person.LastName}";

/*
<Function Name="ParseDouble" ReturnType="Edm.Double">
<Parameter Name="svalue" Type="Edm.String" />
<DefiningExpression>
cast(svalue as Edm.Double)
</DefiningExpression>
</Function>
*/
[ModelDefinedFunction(nameof(ParseDouble), "EntityFramework.Functions.Tests.Examples", @"cast(svalue as Edm.Double)")]
public static double ParseDouble(this string svalue) => double.Parse(svalue);

}
}
12 changes: 12 additions & 0 deletions EntityFramework.Functions.Tests/UnitTests/FunctionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
}
52 changes: 38 additions & 14 deletions EntityFramework.Functions/Function.DbModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ private static IList<FunctionParameter> 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);
}
Expand Down Expand Up @@ -557,12 +557,34 @@ private static IList<FunctionParameter> GetModelParametersForModelDefinedFunctio
this DbModel model, MethodInfo methodInfo)
{
ParameterInfo[] parameters = methodInfo.GetParameters().ToArray();
return parameters
.Select((parameterInfo) => FunctionParameter.Create(
parameterInfo.GetCustomAttribute<ParameterAttribute>()?.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);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

model.GetModelStructualType calls model.GetModelComplexType and model.GetModelEntityType internally, and throw NotSupportedException.

if (type == null)
{
throw new NotSupportedException(
$"{parameterInfo.ParameterType.FullName} for method {methodInfo.Name} is "
+ "not supported in conceptual model");
}
}
}
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should work:

EdmType type;
try
{
type = model.GetModelPrimitiveType(parameterInfo.ParameterType, methodInfo);
}
catch (NotSupportedException exception)
{
type = model.GetModelStructualType(parameterInfo.ParameterType, methodInfo);
}

return FunctionParameter.Create(parameterInfo.GetCustomAttribute<ParameterAttribute>()?.Name ?? parameterInfo.Name,
type,
ParameterMode.In);
}
).ToArray();
}

private static IList<FunctionParameter> GetModelReturnParameters(
Expand Down Expand Up @@ -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.");
//}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed. See comment above.

return modelPrimitiveType;
}
Expand All @@ -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.");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed. See comment above.

}

private static EntityType GetModelEntityType(this DbModel model, Type clrType, MethodInfo methodInfo)
Expand Down