support for method calls on string, this would help database drivers like mongo or even other database that have a string collation that is case sensitive.

This commit is contained in:
David Lebee 2021-04-27 12:51:29 -04:00
parent e7a3b0692e
commit 15aeb2a1a1
2 changed files with 90 additions and 3 deletions

View File

@ -30,6 +30,70 @@ namespace PoweredSoft.DynamicLinq.Test
Assert.IsTrue(newQuery.Any(), "Must have at least one author that matches"); Assert.IsTrue(newQuery.Any(), "Must have at least one author that matches");
} }
[TestMethod]
public void EqualLowerCase()
{
// subject.
var authors = new List<Author>()
{
new Author { Id = long.MaxValue, FirstName = "David", LastName = "Lebee" }
};
// the query.
var query = authors.AsQueryable();
// simple where.
var newQuery = query.Where("FirstName.ToLower()", ConditionOperators.Equal, "david");
// must match.
Assert.IsTrue(newQuery.Any(), "Must have at least one author that matches");
}
[TestMethod]
public void EqualLowerCaseNullCheck()
{
// subject.
var authors = new List<Author>()
{
new Author { Id = long.MaxValue, FirstName = null, LastName = "Lebee" },
new Author { Id = long.MaxValue, FirstName = "David", LastName = "Lebee" },
};
// the query.
var query = authors.AsQueryable();
// simple where.
var newQuery = query.Where(wb =>
{
wb.Equal("FirstName.ToLower()", "david").NullChecking(true);
});
// must match.
Assert.IsTrue(newQuery.Any(), "Must have at least one author that matches");
}
[TestMethod]
public void DoubleMethodCheck()
{
// subject.
var authors = new List<Author>()
{
new Author { Id = long.MaxValue, FirstName = "David ", LastName = "Lebee" },
};
// the query.
var query = authors.AsQueryable();
// simple where.
var newQuery = query.Where(wb =>
{
wb.Equal("FirstName.Trim().ToLower()", "david").NullChecking(true);
});
// must match.
Assert.IsTrue(newQuery.Any(), "Must have at least one author that matches");
}
[TestMethod] [TestMethod]
public void Contains() public void Contains()
{ {

View File

@ -3,6 +3,7 @@ using PoweredSoft.DynamicLinq.Parser;
using PoweredSoft.DynamicLinq.Resolver; using PoweredSoft.DynamicLinq.Resolver;
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
@ -471,8 +472,18 @@ namespace PoweredSoft.DynamicLinq.Helpers
var partStr = parts.First(); var partStr = parts.First();
var isLast = parts.Count == 1; var isLast = parts.Count == 1;
// the member expression. Expression memberExpression;
var memberExpression = Expression.PropertyOrField(current, partStr); if (current != null && current.Type == typeof(string) && partStr.Contains("()"))
{
var finalMethodName = partStr.Replace("()", string.Empty);
var callingMethod = GetStringCallingMethod(finalMethodName); //typeof(string).GetMethod(finalMethodName, new Type[0]);
memberExpression = Expression.Call(current, callingMethod);
}
else
{
// the member expression.
memberExpression = Expression.PropertyOrField(current, partStr);
}
// TODO : maybe support that last part is collection but what do we do? // TODO : maybe support that last part is collection but what do we do?
// not supported yet. // not supported yet.
@ -535,7 +546,19 @@ namespace PoweredSoft.DynamicLinq.Helpers
} }
} }
public static Expression InAndNotIn(ParameterExpression parameter, ConditionOperators condition, object value, QueryConvertStrategy convertStrategy, MemberExpression memberExpression) private static ConcurrentDictionary<string, MethodInfo> _stringMethodCache = new ConcurrentDictionary<string, MethodInfo>();
private static MethodInfo GetStringCallingMethod(string methodName)
{
if (methodName == null)
throw new ArgumentNullException(nameof(methodName));
return _stringMethodCache.GetOrAdd(methodName, mn =>
{
return typeof(string).GetMethod(mn, new Type[0]);
});
}
public static Expression InAndNotIn(ParameterExpression parameter, ConditionOperators condition, object value, QueryConvertStrategy convertStrategy, Expression memberExpression)
{ {
var enumerableValue = value as IEnumerable; var enumerableValue = value as IEnumerable;
if (enumerableValue == null) if (enumerableValue == null)