réponse de remplacement précisions suivantes dans les commentaires:
Pour successivement la construction de filtres supplémentaires, vous n'avez pas besoin d'arbres d'expression; vous pouvez appeler .Where
plusieurs fois (si nécessaire, une fois par terme de recherche) - par exemple:
IEnumerable<DataRow> query = tempResults.AsEnumerable();
if(!string.IsNullOrEmpty(value1)) {
query = query.Where(row => row.Field<string>("Col1") == value1);
}
if (!string.IsNullOrEmpty(value2)) {
query = query.Where(row => row.Field<string>("Col2") == value2);
}
La seule chose à regarder est la question « de capture »; Veillez à ne pas réutiliser l'un des value1
, value2
etc - sinon la dernière valeur s'appliquera aux précédents filtres ...
Pour un exemple de combinaison des délégués (des commentaires) - note que je « ai laissé tomber l'aspect DataTable
ici uniquement pour rendre l'exemple plus court (il fonctionnera de manière identique):
public static class Predicate {
public static Func<T, bool> OrElse<T>(
this Func<T, bool> lhs, Func<T, bool> rhs) {
return lhs == null ? rhs : obj => lhs(obj) || rhs(obj);
}
public static Func<T, bool> AndAlso<T>(
this Func<T, bool> lhs, Func<T, bool> rhs) {
return lhs == null ? rhs : obj => lhs(obj) && rhs(obj);
}
}
class Data {
public string Color { get; set; }
}
class Program {
static void Main() {
bool redChecked = true, greenChecked = true; // from UI...
List<Data> list = new List<Data>() {
new Data { Color = "red"},
new Data { Color = "blue"},
new Data { Color = "green"},
};
Func<Data, bool> filter = null;
if (redChecked) {
filter = filter.OrElse(row => row.Color == "red");
}
if (greenChecked) {
filter = filter.OrElse(row => row.Color == "green");
}
if (filter == null) filter = x => true; // wildcard
var qry = list.Where(filter);
foreach (var row in qry) {
Console.WriteLine(row.Color);
}
}
}
(réponse originale)
En fait, cette variante de LINQ n'utilisera pas d'arborescence d'expression ...il utilisera un délégué; mais vous pouvez construire l'arbre et le compiler si vous voulez vraiment ... Je ne sais pas pourquoi vous le feriez, cependant. Qu'est-ce que tu veux faire? Je vais frapper un exemple ...
Ici vous allez; cela utilise un arbre d'expression, mais je ne peux pas penser à une seule bonne raison de le faire, sinon pour prouver que vous le pouvez!
public static class MyExtensions
{
public static IQueryable<TRow> Where<TRow, TValue>(
this IQueryable<TRow> rows,
string columnName, TValue value)
where TRow : DataRow
{
var param = Expression.Parameter(typeof(TRow), "row");
var fieldMethod = (from method in typeof(DataRowExtensions).GetMethods()
where method.Name == "Field"
&& method.IsGenericMethod
let args = method.GetParameters()
where args.Length == 2
&& args[1].ParameterType == typeof(string)
select method)
.Single()
.MakeGenericMethod(typeof(TValue));
var body = Expression.Equal(
Expression.Call(null,fieldMethod,
param,
Expression.Constant(columnName, typeof(string))),
Expression.Constant(value, typeof(TValue))
);
var lambda = Expression.Lambda<Func<TRow, bool>>(body, param);
return rows.Where(lambda);
}
}
class Program
{
static void Main(string[] args)
{
DataTable tempResults = new DataTable();
tempResults.Columns.Add("ColumnName");
tempResults.Rows.Add("foo");
tempResults.Rows.Add("Column");
var test = tempResults.AsEnumerable().AsQueryable()
.Where("ColumnName", "Column");
Console.WriteLine(test.Count());
}
}
Je veux créer des filtres dynamiques sur les données contenues dans IQueryable tempResults. L'utilisateur va cocher les cases à cocher de l'interface graphique qui ajoutera des expressions "Where" aux données de tempResults. Lorsque l'utilisateur choisit "Colonne", je souhaite présenter les DataRows où ColumnName = "Column". c'est pourquoi j'ai besoin de créer l'expression where. mais je suis tellement coincé sur la chose MethodInfo .... J'ai essayé aussi: MethodInfo FieldStringMethodInfo = type de (DataRowExtensions) .GetMethod ("Champ ", BindingFlags.Public | BindingFlags.Static); cela ne fonctionne pas aussi. Existe-t-il d'autres façons de le faire? –
Rodniko
Ahh! Vous n'avez pas besoin d'arbres d'expression pour cela ... voir mise à jour (dessus de) –
Merci marc, l'exemple Asenumerable() est bon mais j'ai besoin d'un moyen de le créer dynamiquement, car l'utilisateur peut choisir: row = > row.Field ("Col1") == valeur1 || row.Field ("Col1") == valeur2 et la prochaine fois: row => row.Field ("Col1") == value1 || row.Field ("Col1") == valeur2 || row.Field ("Col1") == value3 C'est pourquoi j'ai besoin de le composer dynamiquement, je dois trouver un moyen de "Ajouter les filtres que je veux à une clause where" et ensuite seulement exécuter la requête. puis-je faire cela d'une manière plus simple que l'exemple de l'arbre d'expression? –
Rodniko