J'ai IQueryable type de collecte de données, j'ai fait abstraction d'une méthode, utilisée comme une requête floue plein champ, au début, j'ai été un par un nom d'attribut à écrire. Comme le code suivant:Comment créer une arborescence d'expression pour représenter 'p => p.a.tostring(). Contient ("s")' en C#?
private IQueryable<Tables1> FilterResult(string search, List<Tables1> dtResult)
{
IQueryable<Tables1> results = dtResult.AsQueryable();
results = results.Where(p => (
search == null || (
p.Name != null && p.Name.Contains(search) ||
p.age != null && p.age.ToString().Contains(search) ||
p.sex != null && p.sex.Contains(search) ||
p.content1 != null && p.content1.Contains(search) ||
p.content2 != null && p.content2.Contains(search) ||
p.content3 != null && p.content3.Contains(search)
)
));
return results;
}
Mais cette écriture si le type de changements de collection Liste de réception, tous les attributs physiques doivent ré-écriture. J'ai donc changé le type de T:
private IQueryable<T> FilterResult(string search, List<T> dtResult,T t)
{
IQueryable<T> results = dtResult.AsQueryable();
//do something
return results;
}
L'idée derrière ceci est d'obtenir tous les attributs du type T entrant par réflexion. Puis construisez l'expression Lambda à travers l'arbre d'expression.
La question est de savoir comment construire un 'p => p.age.ToString() .Contains (search)' par Expression Tree?
Ce qui suit est le code complet:
private IQueryable<T> FilterResult(string search, List<T> dtResult, T t)
{
List<Expression> tempExp = new List<Expression>();
var parameter = Expression.Parameter(typeof(T), "p");
foreach (var mi in t.GetType().GetProperties())
{
Expression left = Expression.Property(parameter, t.GetType().GetProperty(mi.Name));
Expression right = Expression.Constant(search, typeof(string));
MethodInfo method;
MethodCallExpression exp;
if (mi.PropertyType == typeof(Int32) || mi.PropertyType == typeof(Int64))
{
//this code is wrong
var exp1 = Expression.Call(Expression.Convert(left, typeof(string)), typeof(object).GetMethod("ToString"));
method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
exp = Expression.Call(exp1, method, right);
}
else
{
method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
exp = Expression.Call(left, method, right);
}
tempExp.Add(exp);
}
Expression all = Expression.Or(Expression.Equal(Expression.Constant(search), null), tempExp[0]);
for (int i = 1; i < tempExp.Count; i++)
{
all = Expression.Or(all, tempExp[i]);
}
var lambda = Expression.Lambda<Func<T, bool>>(all, parameter);
var results = dtResult.Where(lambda.Compile()).AsQueryable(); ;
return results;
}
pourquoi vous retournez un IQueryable? – MBoros