Query builder now supports collections.
Lots of refactoring for this support.
This commit is contained in:
		
							parent
							
								
									507b64c34b
								
							
						
					
					
						commit
						6fa59c3035
					
				@ -99,130 +99,76 @@ namespace PoweredSoft.DynamicLinq.Test
 | 
			
		||||
            Assert.IsTrue(second.Id == 1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //[TestMethod]
 | 
			
		||||
        //public void Test()
 | 
			
		||||
        //{
 | 
			
		||||
        //    var authors = new List<Author>()
 | 
			
		||||
        //    {
 | 
			
		||||
        //        new Author
 | 
			
		||||
        //        {
 | 
			
		||||
        //            Id = 1,
 | 
			
		||||
        //            FirstName = "David",
 | 
			
		||||
        //            LastName = "Lebee",
 | 
			
		||||
        //            Posts = new List<Post>
 | 
			
		||||
        //            {
 | 
			
		||||
        //                new Post
 | 
			
		||||
        //                {
 | 
			
		||||
        //                    Id = 1,
 | 
			
		||||
        //                    AuthorId = 1,
 | 
			
		||||
        //                    Title = "Match",
 | 
			
		||||
        //                    Content = "ABC",
 | 
			
		||||
        //                    Comments = new List<Comment>()
 | 
			
		||||
        //                    {
 | 
			
		||||
        //                        new Comment()
 | 
			
		||||
        //                        {
 | 
			
		||||
        //                            Id = 1,
 | 
			
		||||
        //                            DisplayName = "John Doe",
 | 
			
		||||
        //                            CommentText = "!@#$!@#!@#",
 | 
			
		||||
        //                            Email = "John.doe@me.com"
 | 
			
		||||
        //                        }
 | 
			
		||||
        //                    }
 | 
			
		||||
        //                },
 | 
			
		||||
        //                new Post
 | 
			
		||||
        //                {
 | 
			
		||||
        //                    Id = 2,
 | 
			
		||||
        //                    AuthorId = 1,
 | 
			
		||||
        //                    Title = "Match",
 | 
			
		||||
        //                    Content = "ABC"
 | 
			
		||||
        //                }
 | 
			
		||||
        //            }
 | 
			
		||||
        //        },
 | 
			
		||||
        //        new Author
 | 
			
		||||
        //        {
 | 
			
		||||
        //            Id = 2,
 | 
			
		||||
        //            FirstName = "Chuck",
 | 
			
		||||
        //            LastName = "Norris",
 | 
			
		||||
        //            Posts = new List<Post>
 | 
			
		||||
        //            {
 | 
			
		||||
        //                new Post
 | 
			
		||||
        //                {
 | 
			
		||||
        //                    Id = 3,
 | 
			
		||||
        //                    AuthorId = 2,
 | 
			
		||||
        //                    Title = "Match",
 | 
			
		||||
        //                    Content = "ASD",
 | 
			
		||||
        //                },
 | 
			
		||||
        //                new Post
 | 
			
		||||
        //                {
 | 
			
		||||
        //                    Id = 4,
 | 
			
		||||
        //                    AuthorId = 2,
 | 
			
		||||
        //                    Title = "DontMatch",
 | 
			
		||||
        //                    Content = "ASD",
 | 
			
		||||
        //                }
 | 
			
		||||
        //            }
 | 
			
		||||
        //        }
 | 
			
		||||
        //    };
 | 
			
		||||
        [TestMethod]
 | 
			
		||||
        public void TestCreateFilterExpression()
 | 
			
		||||
        {
 | 
			
		||||
            var authors = new List<Author>()
 | 
			
		||||
            {
 | 
			
		||||
                new Author
 | 
			
		||||
                {
 | 
			
		||||
                    Id = 1,
 | 
			
		||||
                    FirstName = "David",
 | 
			
		||||
                    LastName = "Lebee",
 | 
			
		||||
                    Posts = new List<Post>
 | 
			
		||||
                    {
 | 
			
		||||
                        new Post
 | 
			
		||||
                        {
 | 
			
		||||
                            Id = 1,
 | 
			
		||||
                            AuthorId = 1,
 | 
			
		||||
                            Title = "Match",
 | 
			
		||||
                            Content = "ABC",
 | 
			
		||||
                            Comments = new List<Comment>()
 | 
			
		||||
                            {
 | 
			
		||||
                                new Comment()
 | 
			
		||||
                                {
 | 
			
		||||
                                    Id = 1,
 | 
			
		||||
                                    DisplayName = "John Doe",
 | 
			
		||||
                                    CommentText = "!@#$!@#!@#",
 | 
			
		||||
                                    Email = "John.doe@me.com"
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        new Post
 | 
			
		||||
                        {
 | 
			
		||||
                            Id = 2,
 | 
			
		||||
                            AuthorId = 1,
 | 
			
		||||
                            Title = "Match",
 | 
			
		||||
                            Content = "ABC"
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                new Author
 | 
			
		||||
                {
 | 
			
		||||
                    Id = 2,
 | 
			
		||||
                    FirstName = "Chuck",
 | 
			
		||||
                    LastName = "Norris",
 | 
			
		||||
                    Posts = new List<Post>
 | 
			
		||||
                    {
 | 
			
		||||
                        new Post
 | 
			
		||||
                        {
 | 
			
		||||
                            Id = 3,
 | 
			
		||||
                            AuthorId = 2,
 | 
			
		||||
                            Title = "Match",
 | 
			
		||||
                            Content = "ASD",
 | 
			
		||||
                        },
 | 
			
		||||
                        new Post
 | 
			
		||||
                        {
 | 
			
		||||
                            Id = 4,
 | 
			
		||||
                            AuthorId = 2,
 | 
			
		||||
                            Title = "DontMatch",
 | 
			
		||||
                            Content = "ASD",
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
        //    // the query.
 | 
			
		||||
        //    var query = authors.AsQueryable();
 | 
			
		||||
            // the query.
 | 
			
		||||
            var query = authors.AsQueryable();
 | 
			
		||||
 | 
			
		||||
        //    //// first recursion.
 | 
			
		||||
        //    //var typeOfClass = typeof(Author);
 | 
			
		||||
        //    //var parameter = Expression.Parameter(typeOfClass, "t");
 | 
			
		||||
        //    //var posts = Expression.PropertyOrField(parameter, "Posts");
 | 
			
		||||
 | 
			
		||||
        //    //// second recursion
 | 
			
		||||
        //    //{
 | 
			
		||||
        //    //    var subListType = posts.Type.GetGenericArguments().First();
 | 
			
		||||
 | 
			
		||||
        //    //    var innerParam = Expression.Parameter(subListType, "t2");
 | 
			
		||||
        //    //    var field = Expression.PropertyOrField(innerParam, "Title");
 | 
			
		||||
        //    //    var innerCondition = PoweredSoft.DynamicLinq.Helpers.QueryableHelpers.GetConditionExpressionForMember(innerParam, field, ConditionOperators.Equal, Expression.Constant("Match"));
 | 
			
		||||
        //    //    var lambda = Expression.Lambda(innerCondition, innerParam);
 | 
			
		||||
 | 
			
		||||
        //    //    // any
 | 
			
		||||
        //    //    var anyMethod = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).First(t => t.Name == "All" && t.GetParameters().Count() == 2);
 | 
			
		||||
        //    //    var genericAnyMethod = anyMethod.MakeGenericMethod(subListType);
 | 
			
		||||
        //    //    var subExpression = Expression.Call(genericAnyMethod, posts, lambda);
 | 
			
		||||
 | 
			
		||||
        //    //    var finalLambda = Expression.Lambda<Func<Author, bool>>(subExpression, parameter);
 | 
			
		||||
        //    //    query = query.Where(finalLambda);
 | 
			
		||||
        //    //}
 | 
			
		||||
 | 
			
		||||
        //    var anyMethod = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).First(t => t.Name == "Any" && t.GetParameters().Count() == 2);
 | 
			
		||||
 | 
			
		||||
        //    // first recursion.
 | 
			
		||||
        //    var typeOfClass = typeof(Author);
 | 
			
		||||
        //    var parameter = Expression.Parameter(typeOfClass, "t");
 | 
			
		||||
        //    var posts = Expression.PropertyOrField(parameter, "Posts");
 | 
			
		||||
 | 
			
		||||
        //    // second recursion
 | 
			
		||||
        //    {
 | 
			
		||||
        //        var subListType = posts.Type.GetGenericArguments().First();
 | 
			
		||||
 | 
			
		||||
        //        var innerParam = Expression.Parameter(subListType, "t2");
 | 
			
		||||
        //        var field = Expression.PropertyOrField(innerParam, "Comments");
 | 
			
		||||
 | 
			
		||||
        //        // any
 | 
			
		||||
        //        var genericAnyMethod = anyMethod.MakeGenericMethod(subListType);
 | 
			
		||||
 | 
			
		||||
        //        // third recursion
 | 
			
		||||
        //        {
 | 
			
		||||
        //            var innerParam2 = Expression.Parameter(typeof(Comment), "t3");
 | 
			
		||||
        //            var field2 = Expression.PropertyOrField(innerParam2, "Id");
 | 
			
		||||
        //            var innerCondition2 = QueryableHelpers.GetConditionExpressionForMember(innerParam2, field2, ConditionOperators.Equal, Expression.Constant(1L));
 | 
			
		||||
        //            var lambda = Expression.Lambda(innerCondition2, innerParam2);
 | 
			
		||||
 | 
			
		||||
        //            var generateAnyMethod2 = anyMethod.MakeGenericMethod(typeof(Comment));
 | 
			
		||||
        //            var subExpression2 = Expression.Call(generateAnyMethod2, field, lambda);
 | 
			
		||||
 | 
			
		||||
        //            var previousLambda = Expression.Lambda<Func<Post, bool>>(subExpression2, innerParam);
 | 
			
		||||
 | 
			
		||||
        //            var subExpression = Expression.Call(genericAnyMethod, posts, previousLambda);
 | 
			
		||||
 | 
			
		||||
        //            var finalLambda = Expression.Lambda<Func<Author, bool>>(subExpression, parameter);
 | 
			
		||||
        //            query = query.Where(finalLambda);
 | 
			
		||||
        //        }
 | 
			
		||||
        //    }
 | 
			
		||||
        //}
 | 
			
		||||
            var allExpression = QueryableHelpers.CreateFilterExpression<Author>("Posts.Title", ConditionOperators.Equal, "Match", QueryConvertStrategy.ConvertConstantToComparedPropertyOrField, QueryCollectionCondition.All);
 | 
			
		||||
            var anyExpression = QueryableHelpers.CreateFilterExpression<Author>("Posts.Title", ConditionOperators.Equal, "Match", QueryConvertStrategy.ConvertConstantToComparedPropertyOrField, QueryCollectionCondition.Any);
 | 
			
		||||
            Assert.AreEqual(1, query.Count(allExpression));
 | 
			
		||||
            Assert.AreEqual(2, query.Count(anyExpression));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -25,10 +25,18 @@ namespace PoweredSoft.DynamicLinq
 | 
			
		||||
        ConvertConstantToComparedPropertyOrField
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum QueryCollectionCondition
 | 
			
		||||
    {
 | 
			
		||||
        Any,
 | 
			
		||||
        All
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal static class Constants
 | 
			
		||||
    {
 | 
			
		||||
        internal static readonly MethodInfo ContainsMethod = typeof(string).GetMethod("Contains");
 | 
			
		||||
        internal static readonly MethodInfo StartsWithMethod = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) });
 | 
			
		||||
        internal static readonly MethodInfo EndsWithMethod = typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) });
 | 
			
		||||
        internal static readonly MethodInfo AnyMethod = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).First(t => t.Name == "Any" && t.GetParameters().Count() == 2);
 | 
			
		||||
        internal static readonly MethodInfo AllMethod = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).First(t => t.Name == "All" && t.GetParameters().Count() == 2);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -62,7 +62,7 @@ namespace PoweredSoft.DynamicLinq.Fluent
 | 
			
		||||
            // create a query part.
 | 
			
		||||
            var part = new QueryBuilderFilter();
 | 
			
		||||
            part.And = and;
 | 
			
		||||
            part.Parts = qb.Filters;
 | 
			
		||||
            part.Filters = qb.Filters;
 | 
			
		||||
            Filters.Add(part);
 | 
			
		||||
            
 | 
			
		||||
            //return self.
 | 
			
		||||
@ -156,40 +156,61 @@ namespace PoweredSoft.DynamicLinq.Fluent
 | 
			
		||||
            if (Filters == null || Filters?.Count() == 0)
 | 
			
		||||
                return query;
 | 
			
		||||
 | 
			
		||||
            var parameter = Expression.Parameter(typeof(T), "t");
 | 
			
		||||
            var expression = BuildFilterExpression(parameter, Filters);
 | 
			
		||||
            var lambda = Expression.Lambda<Func<T, bool>>(expression, parameter);
 | 
			
		||||
            query = query.Where(lambda);
 | 
			
		||||
            // shared parameter.
 | 
			
		||||
            var sharedParameter = Expression.Parameter(typeof(T), "t");
 | 
			
		||||
 | 
			
		||||
            // build the expression.
 | 
			
		||||
            var filterExpressionMerged = BuildFilterExpression(sharedParameter, Filters);
 | 
			
		||||
            
 | 
			
		||||
            // make changes on the query.
 | 
			
		||||
            query = query.Where(filterExpressionMerged);
 | 
			
		||||
 | 
			
		||||
            return query;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected virtual Expression BuildFilterExpression(ParameterExpression parameter, List<QueryBuilderFilter> filters)
 | 
			
		||||
        protected virtual Expression<Func<T, bool>> BuildFilterExpression(ParameterExpression parameter, List<QueryBuilderFilter> filters)
 | 
			
		||||
        {
 | 
			
		||||
            Expression ret = null;
 | 
			
		||||
            Expression<Func<T, bool>> temp = null;
 | 
			
		||||
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            filters.ForEach(filter =>
 | 
			
		||||
            {
 | 
			
		||||
                Expression innerExpression;
 | 
			
		||||
                if (filter.Parts?.Any() == true)
 | 
			
		||||
                    innerExpression = BuildFilterExpression(parameter, filter.Parts);
 | 
			
		||||
                Expression<Func<T, bool>> innerExpression;
 | 
			
		||||
                if (filter.Filters?.Any() == true)
 | 
			
		||||
                    innerExpression = BuildFilterExpression(parameter, filter.Filters);
 | 
			
		||||
                else
 | 
			
		||||
                    innerExpression = BuildFilterExpression(parameter, filter);
 | 
			
		||||
 | 
			
		||||
                if (ret != null)
 | 
			
		||||
                    ret = filter.And ? Expression.And(ret, innerExpression) : Expression.Or(ret, innerExpression);
 | 
			
		||||
                if (temp == null)
 | 
			
		||||
                {
 | 
			
		||||
                    temp = innerExpression;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    ret = innerExpression;
 | 
			
		||||
                {
 | 
			
		||||
                    if (filter.And)
 | 
			
		||||
                        temp = Expression.Lambda<Func<T, bool>>(Expression.And(temp.Body, innerExpression.Body), parameter);
 | 
			
		||||
                    else
 | 
			
		||||
                        temp = Expression.Lambda<Func<T, bool>>(Expression.Or(temp.Body, innerExpression.Body), parameter);
 | 
			
		||||
                }
 | 
			
		||||
                    
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            return temp;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected virtual Expression<Func<T, bool>> BuildFilterExpression(ParameterExpression parameter, QueryBuilderFilter filter)
 | 
			
		||||
        {
 | 
			
		||||
            var ret = QueryableHelpers.CreateFilterExpression<T>(
 | 
			
		||||
                filter.Path,
 | 
			
		||||
                filter.ConditionOperator,
 | 
			
		||||
                filter.Value,
 | 
			
		||||
                filter.ConvertStrategy,
 | 
			
		||||
                filter.CollectionHandling,
 | 
			
		||||
                parameter: parameter
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected virtual Expression BuildFilterExpression(ParameterExpression parameter, QueryBuilderFilter filter)
 | 
			
		||||
        {
 | 
			
		||||
            var member = QueryableHelpers.ResolvePathForExpression(parameter, filter.Path);
 | 
			
		||||
            var constant = QueryableHelpers.ResolveConstant(member, filter.Value, filter.ConvertStrategy);
 | 
			
		||||
            var expression = QueryableHelpers.GetConditionExpressionForMember(parameter, member, filter.ConditionOperator, constant);
 | 
			
		||||
            return expression;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,7 @@ namespace PoweredSoft.DynamicLinq.Fluent
 | 
			
		||||
        public object Value { get; set; }
 | 
			
		||||
        public bool And { get; set; }
 | 
			
		||||
        public QueryConvertStrategy ConvertStrategy { get; set; }
 | 
			
		||||
        public List<QueryBuilderFilter> Parts { get; set; } = new List<QueryBuilderFilter>();
 | 
			
		||||
        public List<QueryBuilderFilter> Filters { get; set; } = new List<QueryBuilderFilter>();
 | 
			
		||||
        public QueryCollectionCondition CollectionHandling { get;  set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@ using System.Collections.Generic;
 | 
			
		||||
using System.Data.SqlClient;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Linq.Expressions;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
@ -117,5 +118,103 @@ namespace PoweredSoft.DynamicLinq.Helpers
 | 
			
		||||
            query = query.Provider.CreateQuery<T>(resultExpression);
 | 
			
		||||
            return query;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal static Expression InternalCreateFilterExpression(int recursionStep, Type type, ParameterExpression parameter, Expression current, List<string> parts, 
 | 
			
		||||
            ConditionOperators condition, object value, QueryConvertStrategy convertStrategy, QueryCollectionCondition collectionHandling)
 | 
			
		||||
        {
 | 
			
		||||
            var partStr = parts.First();
 | 
			
		||||
            var isLast = parts.Count == 1;
 | 
			
		||||
 | 
			
		||||
            // the member expression.
 | 
			
		||||
            var memberExpression = Expression.PropertyOrField(current, partStr);
 | 
			
		||||
 | 
			
		||||
            // TODO : maybe support that last part is collection but what do we do?
 | 
			
		||||
            // not supported yet.
 | 
			
		||||
            if (isLast && IsEnumerable(memberExpression))
 | 
			
		||||
                throw new NotSupportedException("Last part must not be a collection");
 | 
			
		||||
 | 
			
		||||
            // create the expression and return it.
 | 
			
		||||
            if (isLast)
 | 
			
		||||
            {
 | 
			
		||||
                var constant = QueryableHelpers.ResolveConstant(memberExpression, value, convertStrategy);
 | 
			
		||||
                var filterExpression = QueryableHelpers.GetConditionExpressionForMember(parameter, memberExpression, condition, constant);
 | 
			
		||||
                var lambda = Expression.Lambda(filterExpression, parameter);
 | 
			
		||||
                return lambda;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            // TODO special handling for collections.
 | 
			
		||||
            if (IsEnumerable(memberExpression))
 | 
			
		||||
            {
 | 
			
		||||
                /* //// first recursion.
 | 
			
		||||
    //var typeOfClass = typeof(Author);
 | 
			
		||||
    //var parameter = Expression.Parameter(typeOfClass, "t");
 | 
			
		||||
    //var posts = Expression.PropertyOrField(parameter, "Posts");
 | 
			
		||||
 | 
			
		||||
    //// second recursion
 | 
			
		||||
    //{
 | 
			
		||||
    //    var subListType = posts.Type.GetGenericArguments().First();
 | 
			
		||||
 | 
			
		||||
    //    var innerParam = Expression.Parameter(subListType, "t2");
 | 
			
		||||
    //    var field = Expression.PropertyOrField(innerParam, "Title");
 | 
			
		||||
    //    var innerCondition = PoweredSoft.DynamicLinq.Helpers.QueryableHelpers.GetConditionExpressionForMember(innerParam, field, ConditionOperators.Equal, Expression.Constant("Match"));
 | 
			
		||||
    //    var lambda = Expression.Lambda(innerCondition, innerParam);
 | 
			
		||||
 | 
			
		||||
    //    // any
 | 
			
		||||
    //    var anyMethod = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).First(t => t.Name == "All" && t.GetParameters().Count() == 2);
 | 
			
		||||
    //    var genericAnyMethod = anyMethod.MakeGenericMethod(subListType);
 | 
			
		||||
    //    var subExpression = Expression.Call(genericAnyMethod, posts, lambda);
 | 
			
		||||
 | 
			
		||||
    //    var finalLambda = Expression.Lambda<Func<Author, bool>>(subExpression, parameter);
 | 
			
		||||
    //    query = query.Where(finalLambda);
 | 
			
		||||
    //}
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
                var listGenericArgumentType = memberExpression.Type.GetGenericArguments().First();
 | 
			
		||||
                var innerParameter = Expression.Parameter(listGenericArgumentType, $"t{++recursionStep}");
 | 
			
		||||
                var innerLambda = InternalCreateFilterExpression(recursionStep, listGenericArgumentType, innerParameter, innerParameter, parts.Skip(1).ToList(), condition, value, convertStrategy, collectionHandling);
 | 
			
		||||
 | 
			
		||||
                // the collection method.
 | 
			
		||||
                var collectionMethod = GetCollectionMethod(collectionHandling);
 | 
			
		||||
                var genericMethod = collectionMethod.MakeGenericMethod(listGenericArgumentType);
 | 
			
		||||
                var callResult = Expression.Call(genericMethod, memberExpression, innerLambda);
 | 
			
		||||
                var expressionResult = Expression.Lambda(callResult, parameter);
 | 
			
		||||
                return expressionResult;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // standard property or field.
 | 
			
		||||
            return InternalCreateFilterExpression(recursionStep, type, parameter, memberExpression, parts.Skip(1).ToList(), condition, value, convertStrategy, collectionHandling);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static MethodInfo GetCollectionMethod(QueryCollectionCondition collectionHandling)
 | 
			
		||||
        {
 | 
			
		||||
            if (collectionHandling == QueryCollectionCondition.All)
 | 
			
		||||
                return Constants.AllMethod;
 | 
			
		||||
            else if (collectionHandling == QueryCollectionCondition.Any)
 | 
			
		||||
                return Constants.AnyMethod;
 | 
			
		||||
 | 
			
		||||
            throw new NotSupportedException($"{collectionHandling} is not supported");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static Expression<Func<T, bool>> CreateFilterExpression<T>(string path, 
 | 
			
		||||
            ConditionOperators condition, 
 | 
			
		||||
            object value, 
 | 
			
		||||
            QueryConvertStrategy convertStrategy, 
 | 
			
		||||
            QueryCollectionCondition collectionHandling = QueryCollectionCondition.Any,
 | 
			
		||||
            ParameterExpression parameter = null)
 | 
			
		||||
        {
 | 
			
		||||
            if (parameter == null)
 | 
			
		||||
                parameter = Expression.Parameter(typeof(T), "t");
 | 
			
		||||
 | 
			
		||||
            var parts = path.Split('.').ToList();
 | 
			
		||||
            var result = InternalCreateFilterExpression(1, typeof(T), parameter, parameter, parts, condition, value, convertStrategy, collectionHandling);
 | 
			
		||||
            var ret = result as Expression<Func<T, bool>>;
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static bool IsEnumerable(MemberExpression member)
 | 
			
		||||
        {
 | 
			
		||||
            var ret = member.Type.FullName.StartsWith("System.Collection");
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user