Skip to content

Commit 71b35bf

Browse files
author
Bart Koelman
committed
Removed duplicate code
1 parent 6a5554e commit 71b35bf

File tree

5 files changed

+37
-43
lines changed

5 files changed

+37
-43
lines changed

src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/QueryClauseBuilder.cs

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -83,30 +83,4 @@ private static MemberExpression CreatePropertyExpressionFromComponents(Expressio
8383

8484
return property!;
8585
}
86-
87-
protected Expression CreateTupleAccessExpressionForConstant(object? value, Type type)
88-
{
89-
// To enable efficient query plan caching, inline constants (that vary per request) should be converted into query parameters.
90-
// https://stackoverflow.com/questions/54075758/building-a-parameterized-entityframework-core-expression
91-
92-
// This method can be used to change a query like:
93-
// SELECT ... FROM ... WHERE x."Age" = 3
94-
// into:
95-
// SELECT ... FROM ... WHERE x."Age" = @p0
96-
97-
// The code below builds the next expression for a type T that is unknown at compile time:
98-
// Expression.Property(Expression.Constant(Tuple.Create<T>(value)), "Item1")
99-
// Which represents the next C# code:
100-
// Tuple.Create<T>(value).Item1;
101-
102-
MethodInfo tupleCreateMethod = typeof(Tuple).GetMethods()
103-
.Single(method => method.Name == "Create" && method.IsGenericMethod && method.GetGenericArguments().Length == 1);
104-
105-
MethodInfo constructedTupleCreateMethod = tupleCreateMethod.MakeGenericMethod(type);
106-
107-
ConstantExpression constantExpression = Expression.Constant(value, type);
108-
109-
MethodCallExpression tupleCreateCall = Expression.Call(constructedTupleCreateMethod, constantExpression);
110-
return Expression.Property(tupleCreateCall, "Item1");
111-
}
11286
}

src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/SkipTakeClauseBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public override Expression VisitPagination(PaginationExpression expression, obje
5252

5353
private Expression ExtensionMethodCall(Expression source, string operationName, int value)
5454
{
55-
Expression constant = CreateTupleAccessExpressionForConstant(value, typeof(int));
55+
Expression constant = value.CreateTupleAccessExpressionForConstant(typeof(int));
5656

5757
return Expression.Call(_extensionType, operationName, LambdaScope.Parameter.Type.AsArray(), source, constant);
5858
}

src/JsonApiDotNetCore/Queries/Internal/QueryableBuilding/WhereClauseBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ public override Expression VisitLiteralConstant(LiteralConstantExpression expres
270270
{
271271
object? convertedValue = expressionType != null ? ConvertTextToTargetType(expression.Value, expressionType) : expression.Value;
272272

273-
return CreateTupleAccessExpressionForConstant(convertedValue, expressionType ?? typeof(string));
273+
return convertedValue.CreateTupleAccessExpressionForConstant(expressionType ?? typeof(string));
274274
}
275275

276276
private static object? ConvertTextToTargetType(string text, Type targetType)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System.Linq.Expressions;
2+
using System.Reflection;
3+
4+
namespace JsonApiDotNetCore.Queries.Internal;
5+
6+
internal static class SystemExpressionExtensions
7+
{
8+
public static Expression CreateTupleAccessExpressionForConstant(this object? value, Type type)
9+
{
10+
// To enable efficient query plan caching, inline constants (that vary per request) should be converted into query parameters.
11+
// https://stackoverflow.com/questions/54075758/building-a-parameterized-entityframework-core-expression
12+
13+
// This method can be used to change a query like:
14+
// SELECT ... FROM ... WHERE x."Age" = 3
15+
// into:
16+
// SELECT ... FROM ... WHERE x."Age" = @p0
17+
18+
// The code below builds the next expression for a type T that is unknown at compile time:
19+
// Expression.Property(Expression.Constant(Tuple.Create<T>(value)), "Item1")
20+
// Which represents the next C# code:
21+
// Tuple.Create<T>(value).Item1;
22+
23+
MethodInfo tupleCreateMethod = typeof(Tuple).GetMethods()
24+
.Single(method => method.Name == "Create" && method.IsGenericMethod && method.GetGenericArguments().Length == 1);
25+
26+
MethodInfo constructedTupleCreateMethod = tupleCreateMethod.MakeGenericMethod(type);
27+
28+
ConstantExpression constantExpression = Expression.Constant(value, type);
29+
30+
MethodCallExpression tupleCreateCall = Expression.Call(constructedTupleCreateMethod, constantExpression);
31+
return Expression.Property(tupleCreateCall, "Item1");
32+
}
33+
}

src/JsonApiDotNetCore/Resources/ResourceFactory.cs

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Linq.Expressions;
22
using System.Reflection;
3+
using JsonApiDotNetCore.Queries.Internal;
34
using Microsoft.Extensions.DependencyInjection;
45

56
namespace JsonApiDotNetCore.Resources;
@@ -72,8 +73,7 @@ public NewExpression CreateNewExpression(Type resourceClrType)
7273
{
7374
object constructorArgument = ActivatorUtilities.GetServiceOrCreateInstance(_serviceProvider, constructorParameter.ParameterType);
7475

75-
Expression argumentExpression = CreateTupleAccessExpressionForConstant(constructorArgument, constructorArgument.GetType());
76-
76+
Expression argumentExpression = constructorArgument.CreateTupleAccessExpressionForConstant(constructorArgument.GetType());
7777
constructorArguments.Add(argumentExpression);
7878
}
7979
#pragma warning disable AV1210 // Catch a specific exception instead of Exception, SystemException or ApplicationException
@@ -88,19 +88,6 @@ public NewExpression CreateNewExpression(Type resourceClrType)
8888
return Expression.New(longestConstructor, constructorArguments);
8989
}
9090

91-
private static Expression CreateTupleAccessExpressionForConstant(object value, Type type)
92-
{
93-
MethodInfo tupleCreateMethod = typeof(Tuple).GetMethods()
94-
.Single(method => method.Name == "Create" && method.IsGenericMethod && method.GetGenericArguments().Length == 1);
95-
96-
MethodInfo constructedTupleCreateMethod = tupleCreateMethod.MakeGenericMethod(type);
97-
98-
ConstantExpression constantExpression = Expression.Constant(value, type);
99-
100-
MethodCallExpression tupleCreateCall = Expression.Call(constructedTupleCreateMethod, constantExpression);
101-
return Expression.Property(tupleCreateCall, "Item1");
102-
}
103-
10491
private static bool HasSingleConstructorWithoutParameters(Type type)
10592
{
10693
ConstructorInfo[] constructors = type.GetConstructors().Where(constructor => !constructor.IsStatic).ToArray();

0 commit comments

Comments
 (0)