dbelmont / ExpressionBuilder

A library that provides a simple way to create lambda expressions to filter lists and database queries.
Apache License 2.0
372 stars 105 forks source link

Add operations Any and Not Any #62

Open dust63 opened 4 years ago

dust63 commented 4 years ago

Hi,

I use your lib and it was very usefull. I add some operations like Any or NotAny for List type. I think it could be interesting to add this operations to your lib.

I also add method to filter by property expression. Example: filter.By<Student>(x=> x.Director.Name, Operations.Equal, "test");

I think it provides more flexibility for the dev to use string property description or expression property.

dust63 commented 4 years ago

` ///

/// If Enumerable have no elements or is null. /// public class NotAnyOrNull : OperationBase {

    public NotAnyOrNull() : base("NotAnyOrNull", 0, TypeGroup.Enumerable, true, true)
    {
    }

    private static MethodInfo GetAnyMethod(MemberExpression member)
    {
        var enumerableType = typeof(Enumerable);
        var anyInfo = enumerableType.GetMethods(BindingFlags.Static | BindingFlags.Public).First(m => m.Name == "Any" && m.GetParameters().Count() == 1);
        return anyInfo.MakeGenericMethod(member.Type.GetGenericArguments().First());
    }

    // This is where your operation's behaviour lives
    // In this example, we are checking if the property's day and month are the same as today's day and month
    public override Expression GetExpression(MemberExpression member, ConstantExpression constant1, ConstantExpression constant2)
    {
        return Expression.OrElse(
            Expression.Equal(member, Expression.Constant(null)),
            Expression.Not(Expression.Call(GetAnyMethod(member), member)));
    }

    public override string ToString()
    {
        return Name;
    }
}`
dust63 commented 4 years ago

` ///

/// If Enumerable have elements and not null. /// public class AnyAndNotNull : OperationBase {

    public AnyAndNotNull() : base("AnyAndNotNull", 0, TypeGroup.Enumerable, true, true) { }

    private static MethodInfo GetAnyMethod(MemberExpression member)
    {
        var enumerableType = typeof(Enumerable);
        var anyInfo = enumerableType.GetMethods(BindingFlags.Static | BindingFlags.Public).First(m => m.Name == "Any" && m.GetParameters().Count() == 1);
        return anyInfo.MakeGenericMethod(member.Type.GetGenericArguments().First());
    }

    // This is where your operation's behaviour lives
    // In this example, we are checking if the property's day and month are the same as today's day and month
    public override Expression GetExpression(MemberExpression member, ConstantExpression constant1, ConstantExpression constant2)
    {
        return Expression.AndAlso(
            Expression.NotEqual(member, Expression.Constant(null)),
            Expression.Call(GetAnyMethod(member), member));
    }

}`