locked
expression to lower not working RRS feed

  • Question

  • User1080785583 posted

    Is this a good way to build lower case expression searching? I seem to be tripping on this

    Here is not working code....

    public override Expression<Func<ExpressionTest.Company, bool>> FilterBy(string propertyName, ExpressionTest.SearchType searchType, string searchValue)
            {
                try
                {
                    //searchValue = searchValue.ToLower();
                    var paramStart = Expression.Parameter(typeof(ExpressionTest.Company), "x");
    
                    // Compose the expression tree that represents the parameter to the predicate.
                    ParameterExpression pe = Expression.Parameter(typeof(string), propertyName);
    
                    // create a tree that represents the expression 'Name.ToLower contains "x"
                    //Expression left = Expression.Call(pe, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));
                    //Expression right = Expression.Constant(searchValue);
                    //Expression lowerCase = Expression.Equal(left, right);
    
                    Expression<Func<ExpressionTest.Company, bool>> searchExpression = Expression
                        .Lambda<Func<ExpressionTest.Company, bool>>(
                            Expression.Call(
                                // first parameter .call
                                Expression.Property(paramStart,
                                // first
                                typeof(ExpressionTest.Company).GetProperty(propertyName).GetGetMethod()),
                                // second
                                typeof(String).GetMethod(searchType.ToString(), new Type[] { typeof(String) }),
                                // third
                                new Expression[] { Expression.Constant(searchValue, typeof(string)) }),
                                //new Expression[]{ lowerCase}),
                            new ParameterExpression[] { paramStart });
    
                    return searchExpression;
                }
                catch
                {
                    throw;
                }
            }

    Here is working code...

    public override Expression<Func<ExpressionTest.Company, bool>> FilterBy(string propertyName, ExpressionTest.SearchType searchType, string searchValue)
            {
                try
                {
                    var paramStart = Expression.Parameter(typeof(ExpressionTest.Company), "x"); 
                    Expression<Func<ExpressionTest.Company, bool>> searchExpression = Expression
                        .Lambda<Func<ExpressionTest.Company, bool>>(
                            Expression.Call(Expression.Property(paramStart,
                                typeof(ExpressionTest.Company).GetProperty(propertyName).GetGetMethod()),
                                typeof(String).GetMethod(searchType.ToString(), new Type[] { typeof(String) }),
                                new Expression[] { Expression.Constant(searchValue, typeof(string)) }),
                            new ParameterExpression[] { paramStart });
    
                    return searchExpression;
                }
                catch
                {
                    throw;
                }
            }

    I found some other code that does to lower by generating method call of lambda, but I am unable to see how I can keep it as an Expression<Func<T,bool>>

     [TestMethod]
            public void BossTest()
            {
                // Add a using directive for System.Linq.Expressions. 
    
                string[] companies = { "Consolidated Messenger", "Alpine Ski House", "Southridge Video", "City Power & Light",
                                   "Coho Winery", "Wide World Importers", "Graphic Design Institute", "Adventure Works",
                                   "Humongous Insurance", "Woodgrove Bank", "Margie's Travel", "Northwind Traders",
                                   "Blue Yonder Airlines", "Trey Research", "The Phone Company",
                                   "Wingtip Toys", "Lucerne Publishing", "Fourth Coffee" };
    
                // The IQueryable data to query.
                IQueryable<String> queryableData = companies.AsQueryable<string>();
    
                // Compose the expression tree that represents the parameter to the predicate.
                ParameterExpression pe = Expression.Parameter(typeof(string), "company");
    
                // ***** Where(company => (company.ToLower() == "coho winery" || company.Length > 16)) *****
                // Create an expression tree that represents the expression 'company.ToLower() == "coho winery"'.
                Expression left = Expression.Call(pe, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));
                Expression right = Expression.Constant("coho winery");
                Expression e1 = Expression.Equal(left, right);
    
                // Create an expression tree that represents the expression 'company.Length > 16'.
                left = Expression.Property(pe, typeof(string).GetProperty("Length"));
                right = Expression.Constant(16, typeof(int));
                Expression e2 = Expression.GreaterThan(left, right);
    
                // Combine the expression trees to create an expression tree that represents the 
                // expression '(company.ToLower() == "coho winery" || company.Length > 16)'.
                Expression predicateBody = Expression.OrElse(e1, e2);
    
                // Create an expression tree that represents the expression 
                // 'queryableData.Where(company => (company.ToLower() == "coho winery" || company.Length > 16))'
                MethodCallExpression whereCallExpression = Expression.Call(
                    typeof(Queryable),
                    "Where",
                    new Type[] { queryableData.ElementType },
                    queryableData.Expression,
                    Expression.Lambda<Func<string, bool>>(predicateBody, new ParameterExpression[] { pe }));
                // ***** End Where ***** 
    
                // ***** OrderBy(company => company) ***** 
                // Create an expression tree that represents the expression 
                // 'whereCallExpression.OrderBy(company => company)'
                MethodCallExpression orderByCallExpression = Expression.Call(
                    typeof(Queryable),
                    "OrderBy",
                    new Type[] { queryableData.ElementType, queryableData.ElementType },
                    whereCallExpression,
                    Expression.Lambda<Func<string, string>>(pe, new ParameterExpression[] { pe }));
                // ***** End OrderBy ***** 
    
                // Create an executable query from the expression tree.
                IQueryable<string> results = queryableData.Provider.CreateQuery<string>(orderByCallExpression);
    
                // Enumerate the results. 
                //foreach (string company in results)
                //    Console.WriteLine(company);
                var found = results.ToList();
    
                Assert.IsTrue(found.Any());
            }

    This is what I get back from my WORKING CODE...

    System.Linq.Expressions.Expression.MethodCallExpressionProxy(((System.Linq.EnumerableQuery)(queryable)).Expression as System.Linq.Expressions.MethodCallExpressionN)).DebugView

    .Call System.Linq.Queryable.Where( .Constant<system.linq.enumerablequery`1[posd.unittests.unit.expressiontest+company]>(System.Collections.Generic.List`1[POSD.UnitTests.Unit.ExpressionTest+Company]), '(.Lambda #Lambda1<system.func`2[posd.unittests.unit.expressiontest+company,system.boolean]>)) .Lambda #Lambda1<system.func`2[posd.unittests.unit.expressiontest+company,system.boolean]>(POSD.UnitTests.Unit.ExpressionTest+Company $x) { .Call ($x.Name).Contains("Nin") }

    Tuesday, December 9, 2014 6:13 PM

Answers

  • User1080785583 posted

    {x => (x.Name.IndexOf("NIN", InvariantCultureIgnoreCase) >= 0)}

    {System.Collections.Generic.List`1[POSD.UnitTests.Unit.ExpressionTest+Company].Where(x => (x.Name.IndexOf("NIN", InvariantCultureIgnoreCase) >= 0))}

    {x => x.Name.Contains("NIN")}

    {System.Collections.Generic.List`1[POSD.UnitTests.Unit.ExpressionTest+Company].Where(x => x.Name.Contains("NIN"))}

    IndexOf fixes it.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, December 10, 2014 1:44 PM