Skip to content

Commit

Permalink
Merge pull request #19 from mrahhal/sql-parameters
Browse files Browse the repository at this point in the history
Generate expressions to use sql parameters instead of constants
  • Loading branch information
mrahhal authored Jun 16, 2022
2 parents 7d005dc + 88848a0 commit 8aceaa0
Showing 1 changed file with 16 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ private static Expression<Func<T, bool>> BuildKeysetFilterPredicateExpression<T>
var referenceValues = GetValues(items, reference);

var firstMemberAccessExpression = default(MemberExpression);
var firstReferenceValueExpression = default(ConstantExpression);
var firstReferenceValueExpression = default(Expression);

// entity =>
var param = Expression.Parameter(typeof(T), "entity");
Expand All @@ -273,7 +273,9 @@ private static Expression<Func<T, bool>> BuildKeysetFilterPredicateExpression<T>
var isInnerLastOperation = j + 1 == innerLimit;
var item = items[j];
var memberAccess = Expression.MakeMemberAccess(param, item.Property);
var referenceValueExpression = Expression.Constant(referenceValues[j]);
var referenceValue = referenceValues[j];
Expression<Func<object>> referenceValueFunc = () => referenceValue;
var referenceValueExpression = referenceValueFunc.Body;

if (firstMemberAccessExpression == null)
{
Expand Down Expand Up @@ -330,7 +332,7 @@ private static Expression<Func<T, bool>> BuildKeysetFilterPredicateExpression<T>

private static BinaryExpression MakeComparisonExpression<T>(
KeysetPaginationItem<T> item,
MemberExpression memberAccess, ConstantExpression referenceValue,
MemberExpression memberAccess, Expression referenceValue,
Func<Expression, Expression, BinaryExpression> compare)
where T : class
{
Expand All @@ -340,11 +342,14 @@ private static BinaryExpression MakeComparisonExpression<T>(
// LessThan/GreaterThan operators are not valid for some types such as strings and guids.
// We use the CompareTo method on these types instead.

// entity.Property.CompareTo(constant) >|< 0
// entity.Property.CompareTo(referenceValue) >|< 0
// -----------------------------------------

// entity.Property.CompareTo(constant)
var methodCallExpression = Expression.Call(memberAccess, compareToMethod, referenceValue);
// entity.Property.CompareTo(referenceValue)
var methodCallExpression = Expression.Call(
memberAccess,
compareToMethod,
EnsureMatchingType(memberAccess, referenceValue));

// >|< 0
return compare(methodCallExpression, ConstantExpression0);
Expand All @@ -361,21 +366,18 @@ private static Expression EnsureMatchingType(
MemberExpression memberExpression,
Expression targetExpression)
{
// If the member is nullable we'll have to make sure the target type matches or else comparison/equal
// expressions won't work because of unmatching types.
if (IsNullableType(memberExpression.Type) && memberExpression.Type != targetExpression.Type)
// If the target has a different type we should convert it.
// Originally this happened with nullables only, but now that we use expressions
// for the target access instead of constants we'll need this or else comparison won't work
// between unmatching types (i.e int (member) compared to object (target)).
if (memberExpression.Type != targetExpression.Type)
{
return Expression.Convert(targetExpression, memberExpression.Type);
}

return targetExpression;
}

private static bool IsNullableType(Type type)
{
return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
}

private static Func<Expression, Expression, BinaryExpression> GetComparisonExpressionToApply<T>(
KeysetPaginationDirection direction, KeysetPaginationItem<T> item, bool orEqual)
where T : class
Expand Down

0 comments on commit 8aceaa0

Please sign in to comment.