| | 1 | | using System.Data; |
| | 2 | | using System.Diagnostics; |
| | 3 | | using System.Reflection; |
| | 4 | |
|
| | 5 | | namespace Pozitron.QuerySpecification; |
| | 6 | |
|
| | 7 | | internal static class LikeExtension |
| | 8 | | { |
| 1 | 9 | | private static readonly MethodInfo _likeMethodInfo = typeof(DbFunctionsExtensions) |
| 1 | 10 | | .GetMethod(nameof(DbFunctionsExtensions.Like), [typeof(DbFunctions), typeof(string), typeof(string)])!; |
| | 11 | |
|
| 1 | 12 | | private static readonly PropertyInfo _functionsProp = typeof(EF).GetProperty(nameof(EF.Functions))!; |
| 1 | 13 | | private static readonly MemberExpression _functions = Expression.Property(null, _functionsProp); |
| | 14 | |
|
| | 15 | | public static IQueryable<T> Like<T>(this IQueryable<T> source, IEnumerable<LikeExpression<T>> likeExpressions) |
| | 16 | | { |
| | 17 | | Debug.Assert(_likeMethodInfo is not null); |
| | 18 | | Debug.Assert(_functionsProp is not null); |
| | 19 | |
|
| 21 | 20 | | Expression? expr = null; |
| 21 | 21 | | var parameter = Expression.Parameter(typeof(T), "x"); |
| | 22 | |
|
| 102 | 23 | | foreach (var likeExpression in likeExpressions) |
| | 24 | | { |
| 30 | 25 | | var propertySelector = ParameterReplacerVisitor.Replace( |
| 30 | 26 | | likeExpression.KeySelector, |
| 30 | 27 | | likeExpression.KeySelector.Parameters[0], |
| 30 | 28 | | parameter) as LambdaExpression; |
| | 29 | |
|
| | 30 | | Debug.Assert(propertySelector is not null); |
| | 31 | |
|
| 30 | 32 | | var patternAsExpression = ((Expression<Func<string>>)(() => likeExpression.Pattern)).Body; |
| | 33 | |
|
| 30 | 34 | | var efLikeExpression = Expression.Call( |
| 30 | 35 | | null, |
| 30 | 36 | | _likeMethodInfo, |
| 30 | 37 | | _functions, |
| 30 | 38 | | propertySelector.Body, |
| 30 | 39 | | patternAsExpression); |
| | 40 | |
|
| 30 | 41 | | expr = expr is null ? efLikeExpression : Expression.OrElse(expr, efLikeExpression); |
| | 42 | | } |
| | 43 | |
|
| 21 | 44 | | return expr is null |
| 21 | 45 | | ? source |
| 21 | 46 | | : source.Where(Expression.Lambda<Func<T, bool>>(expr, parameter)); |
| | 47 | | } |
| | 48 | | } |