Creating a LINQ Query Using Expression Trees

Update

Thanks Marc to help AlphaPagedList class is now available on CodePlex if anyone is interested

Original

I am trying to create an expression tree to return elements starting with the given charecter.

IList<char> chars = new List<char>{'a','b'}; IQueryable<Dept>Depts.Where(x=> chars.Contains(x.DeptName[0])); 

I want this to be used in any IEnumerable, where I provide the lamdba property for selection, for example:

Depts.Alpha(x=>x.DeptName, chars);

I tried this, but I'm out of luck, any help?

 public static IQueryable<T> testing<T>(this IQueryable<T> queryableData, Expression<Func<T,string>> pi, IEnumerable<char> chars) { // Compose the expression tree that represents the parameter to the predicate. ParameterExpression pe = Expression.Parameter(queryableData.ElementType, "x"); ConstantExpression ch = Expression.Constant(chars,typeof(IEnumerable<char>)); // ***** Where(x=>chars.Contains(x.pi[0])) ***** // pi is a string property //Get the string property Expression first = Expression.Constant(0); //Get the first character of the string Expression firstchar = Expression.ArrayIndex(pi.Body, first); //Call "Contains" on chars with argument being right Expression e = Expression.Call(ch, typeof(IEnumerable<char>).GetMethod("Contains", new Type[] { typeof(char) }),firstchar); MethodCallExpression whereCallExpression = Expression.Call( typeof(Queryable), "Where", new Type[] { queryableData.ElementType }, queryableData.Expression, Expression.Lambda<Func<T, bool>>(e, new ParameterExpression[] { pe })); // ***** End Where ***** return (queryableData.Provider.CreateQuery<T>(whereCallExpression)); } 
+4
source share
1 answer

Something like ( EDITED after re-reading the question) - but note that Expression.Invoke does not work in EF in 3.5SP1 (but this is normal in LINQ-to-SQL):

 using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; class Dept { public string DeptName { get; set; } } public static class Program { static void Main() { IList<char> chars = new List<char>{'a','b'}; Dept[] depts = new[] { new Dept { DeptName = "alpha" }, new Dept { DeptName = "beta" }, new Dept { DeptName = "omega" } }; var count = testing(depts.AsQueryable(), dept => dept.DeptName, chars).Count(); } public static IQueryable<T> testing<T>(this IQueryable<T> queryableData, Expression<Func<T,string>> pi, IEnumerable<char> chars) { var arg = Expression.Parameter(typeof(T), "x"); var prop = Expression.Invoke(pi, arg); Expression body = null; foreach(char c in chars) { Expression thisFilter = Expression.Call(prop, "StartsWith", null, Expression.Constant(c.ToString())); body = body == null ? thisFilter : Expression.OrElse(body, thisFilter); } var lambda = Expression.Lambda<Func<T, bool>>(body ?? Expression.Constant(false), arg); return queryableData.Where(lambda); } } 
+2
source

Source: https://habr.com/ru/post/1305022/


All Articles