Pour effectuer cette tâche, il est nécessaire d'implémenter deux Fonctions:
Or
expression_table fonction
- filtre fonction split de données
ou la fonction passe par une collection d'expressions et les rejoint dans une expression Or
comme (((expression1 or expression2) or expression3) or expression4)
public static Expression<Func<T, bool>> Or<T>(
this IEnumerable<Expression<Func<T, bool>>> source)
{
var expressions = source.ToList();
if (expressions.Count == 0)
return x => false;
var orExpression = expressions
.Select(e => e.Body)
.Aggregate((a, b) => Expression.OrElse(a, b));
var parameter = expressions.First().Parameters.First();
return Expression.Lambda<Func<T, bool>>(orExpression, parameter);
}
Cette La fonction peut déjà être utilisée si les filtres sont déjà des expressions valides.
La fonction de partage de données de filtre doit multiplier l'expression du sélecteur et remplacer dans le paramètre d'expression de résultat par la valeur exacte de l'objet. population de données de filtrage se fait dans la fonction:
public static IEnumerable<Expression<Func<T, bool>>> Filter<T, TData>(
this IEnumerable<TData> data,
Expression<Func<T,TData, bool>> selector)
{
var parameter = selector.Parameters.First(p => p.Type.IsAssignableFrom(typeof(T)));
return data.Select(item => Expression.Lambda<Func<T, bool>>(
new DataVisitor<TData>(item).Visit(selector.Body), parameter));
}
mise en œuvre des visiteurs suivante permet de remplacer le paramètre avec la valeur exacte:
public class DataVisitor<T> : ExpressionVisitor
{
private readonly ConstantExpression _data;
public DataVisitor(T dataItem)
{
_data = Expression.Constant(dataItem);
}
protected override Expression VisitParameter(ParameterExpression node)
{
return node.Type.IsAssignableFrom(typeof(T))
? _data : base.VisitParameter(node);
}
}
La construction d'expression est une expression lambda correcte qui peut être analysé par l'EF analyseur d'arbre d'expression.