Cómo crear un predicado dinámicamente.

Hola, quiero crear una lista basada en la cadena de búsqueda usando expresiones de predicado.

Tengo una lista de productos de tipo contiene diferentes nombres.

List list1 = new List(); list1.Add(new products("sowmya")); list1.Add(new products("Jane")); list1.Add(new products("John")); list1.Add(new products("kumar")); list1.Add(new products("ramya")); listBox1.ItemsSource = list1; 

Ahora quiero filtrar el contenido según la entrada del usuario. El usuario ingresará n no de cadenas con ‘+’ como separador. Después de recibir las cadenas, las pasaré al objeto de predicado como este.

  private void textBox1_KeyDown(object sender, KeyEventArgs e) { List list2 = new List(); Expression<Func> predicate = PredicateBuilder.True(); if (e.Key == Key.Enter) { string Searchstring = textBox1.Text.ToString().Trim(); string[] separator = new string[] { "+" }; string[] SearchItems=Searchstring.Split(separator,StringSplitOptions.None); foreach (string str in SearchItems) { string temp = str; predicate =p => p.Name.Contains(temp.ToLower()); } list2 = list1.AsQueryable().Where(predicate).ToList(); listBox1.ItemsSource = list2; } } 

Si introduzco más de una cadena (sowmya + jane + john), solo da el resultado de la última cadena (john) pero quiero una lista de todas las cadenas coincidentes

Por favor, responda esta pregunta porque estoy intentando esto pero no pude obtener el resultado.

Por favor, ayuda un poco gracias.

Inicializa el predicado como falso

 Expression> predicate = PredicateBuilder.False(); 

Necesitas combinar los predicados usando Or

 foreach (string str in SearchItems) { string temp = str; predicate = predicate.Or(p => p.NameToLower().Contains(temp.ToLower())); } 

Fuente para el constructor de predicados aquí . Es parte de LINQKit

Código, en caso de enlace va

 using System; using System.Linq; using System.Linq.Expressions; using System.Collections.Generic; public static class PredicateBuilder { public static Expression> True () { return f => true; } public static Expression> False () { return f => false; } public static Expression> Or (this Expression> expr1, Expression> expr2) { var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast ()); return Expression.Lambda> (Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters); } public static Expression> And (this Expression> expr1, Expression> expr2) { var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast ()); return Expression.Lambda> (Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters); } } 

No tienes que construir un predicado aquí. Puedes probar algo como esto

 List list1 = new List(); list1.Add(new products("sowmya")); list1.Add(new products("Jane")); list1.Add(new products("John")); list1.Add(new products("kumar")); list1.Add(new products("ramya")); string input = "aaa+kuma+ram"; List searchStrings = input.Split(new string[] { "+" }, StringSplitOptions.None) .Select(s => s.ToLower()) .ToList(); List list2 = ( from p in list1 where searchStrings.Any(s => p.Name.Contains(s)) select p).ToList(); 

list2 contendrá “kumar” y “ramya”.

Como no estoy seguro de que la instancia de predicado tenga un método And, le sugiero que use este código:

 var list = list1.AsQueryable(); foreach (string str in SearchItems) { list = list.Where(p => p.Name.ToLower().Contains(str.ToLower())); } listBox1.ItemsSource = list.ToList();