Let's say we are using EF6, and db is the EF DbContext. Let's say the user could enter five possible queries:
    enum Operator
    {
        EQUAL,
        NOT_EQUAL,    
        LESS_THAN, 
        MORE_THAN,
        ANY
    };
    var operator = //some user selected operator, out of the ones available in the enum above
    var carAge = //int selected by user to specify desired age
    List cars; 
    switch(operator)
    {
        case Operator.EQUAL 
        {
            cars = db.Cars.Where(c=> c.Age == carAge).ToList(); 
        }
        case Operator.NOT_EQUAL 
        {
            cars = db.Cars.Where(c=> c.Age != carAge).ToList(); 
        }
        case Operator.LESS_THAN 
        {
            cars = db.Cars.Where(c=> c.Age  c.Age > carAge).ToList(); 
        }
        case Operator.ANY 
        {
            cars = db.Cars.ToList(); 
        }
    }
 
How do I do this more efficiently? The switch operator seems silly. It looks like this article is answering the question, but I don't fully understand.
We do have an answer on dynamically building multiple queries, but that's a different part of what I want (would apply if question was "User can search for both car age and mileage, or neither).
Edit: To clarify in response to a comment, my "goal" is any standard search, using the car example, a user would have a number of fields where they can select operators. They can use any, all, or no fields, e.g.
Mileage: Operator, Value
Year: Operator, Value
Brand: (is/is not, for example), Car brands 
    Expression<Func<T, bool>> Build<T, TProperty>(Expression<Func<T, TProperty>> property, Operator op, TProperty value)
    {
        if (op == Operator.ANY)
        {
            return e => true;
        }
        var left = property.Body;   //you need to check if it's a valid property visit
        var right = Expression.Constant(value);
        BinaryExpression body;
        switch (op)
        {
            case Operator.EQUAL:
                body = Expression.Equal(left, right);
                break;
            case Operator.NOT_EQUAL:
                body = Expression.NotEqual(left, right);
                break;
            case Operator.LESS_THAN:
                //you'd better check if < operator is available for the type
                body = Expression.LessThan(left, right);
                break;
            case Operator.MORE_THAN:
                body = Expression.GreaterThan(left, right);
                break;
            default: throw new NotSupportedException();
        }
        return Expression.Lambda<Func<T, bool>>(body, property.Parameters[0]);
    }
Usage var bmw = Build<Car, string>(c => c.Brand, Operator.EQUAL, "BMW");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With