Return lambda expression based on parameters This function returns a lambda expression based on the parameters sent. I am sure there is a better way to do this.

    [NonAction]
    private Expression&lt;Func&lt;ScheduleItemDto, bool&gt;&gt; Where(Guid siteGuid, Guid? eventGuid, MonthOfYear month, int year, bool? closed)
    {
        Expression&lt;Func&lt;ScheduleItemDto, bool&gt;&gt; notAdminExpression = x =&gt; x.Active == true;
        Expression&lt;Func&lt;ScheduleItemDto, bool&gt;&gt; baseExpression = x =&gt; x.SiteGuid == siteGuid &amp;&amp; x.Date.Month == (int)month + 1 &amp;&amp; x.Date.Year == year;
        Expression&lt;Func&lt;ScheduleItemDto, bool&gt;&gt; eventExpression = x =&gt; x.EventGuid == eventGuid;
        Expression&lt;Func&lt;ScheduleItemDto, bool&gt;&gt; closedExpression = x =&gt; x.Closed != null;
        Expression&lt;Func&lt;ScheduleItemDto, bool&gt;&gt; notClosedExpression = x =&gt; x.Closed == null;
        Expression&lt;Func&lt;ScheduleItemDto, bool&gt;&gt; resultExpression = x =&gt; true;

        switch (closed)
        {
            case null:
                if (eventGuid == null)
                {
                    resultExpression = baseExpression;                      
                }
                else
                {
                    resultExpression = Expression.Lambda&lt;Func&lt;ScheduleItemDto, bool&gt;&gt;(Expression.AndAlso(baseExpression.Body, eventExpression.Body), baseExpression.Parameters[0]);
                }
                break;

            case true:
                if (eventGuid == null)
                {
                    resultExpression = Expression.Lambda&lt;Func&lt;ScheduleItemDto, bool&gt;&gt;(Expression.AndAlso(baseExpression.Body, closedExpression.Body), baseExpression.Parameters[0]);
                }
                else
                {
                    Expression&lt;Func&lt;ScheduleItemDto, bool&gt;&gt; exp = Expression.Lambda&lt;Func&lt;ScheduleItemDto, bool&gt;&gt;(Expression.AndAlso(baseExpression.Body, closedExpression.Body), baseExpression.Parameters[0]);
                    resultExpression = Expression.Lambda&lt;Func&lt;ScheduleItemDto, bool&gt;&gt;(Expression.AndAlso(exp.Body, eventExpression.Body), exp.Parameters[0]);
                }
                break;

            case false:
                if (eventGuid == null)
                {
                    resultExpression = Expression.Lambda&lt;Func&lt;ScheduleItemDto, bool&gt;&gt;(Expression.AndAlso(baseExpression.Body, notClosedExpression.Body), baseExpression.Parameters[0]);
                }
                else
                {
                    Expression&lt;Func&lt;ScheduleItemDto, bool&gt;&gt; exp = Expression.Lambda&lt;Func&lt;ScheduleItemDto, bool&gt;&gt;(Expression.AndAlso(baseExpression.Body, notClosedExpression.Body), baseExpression.Parameters[0]);
                    resultExpression = Expression.Lambda&lt;Func&lt;ScheduleItemDto, bool&gt;&gt;(Expression.AndAlso(exp.Body, eventExpression.Body), exp.Parameters[0]);
                }
                break;
        }

        if (!AccessControl.HasAccess(Permissions.DashboardAdministrator))
        {
            return Expression.Lambda&lt;Func&lt;ScheduleItemDto, bool&gt;&gt;(Expression.AndAlso(resultExpression.Body, notAdminExpression.Body), resultExpression.Parameters[0]);
        }

        return resultExpression;
    }
Personally, I find your code easy enough to follow. The flow control is lengthy but is quite simple. A few notes before searching alternatives for the flow control.



Expression&lt;Func&lt;ScheduleItemDto, bool&gt;&gt; notAdminExpression = x =&gt; x.Active == true;


Could be

Expression&lt;Func&lt;ScheduleItemDto, bool&gt;&gt; notAdminExpression = x =&gt; x.Active;




Your function could be broken in two pieces, one for the switch statement and another for the permission part. It may be a matter of personal preference, but allows early return statements, removing the assignment operation and thus entirely removing any state from the function, pure functions are easier to follow.

// ...
case null:
    if (eventGuid == null)
    {
        return baseExpression;                      
    }
    else
    {
        return Expression.Lambda&lt;Func&lt;ScheduleItemDto, bool&gt;&gt;(Expression.AndAlso(baseExpression.Body, eventExpression.Body), baseExpression.Parameters[0]);
    }
// ...

private Expression&lt;Func&lt;ScheduleItemDto, bool&gt;&gt; RestrictPermission(Expression&lt;Func&lt;ScheduleItemDto, bool&gt;&gt; baseExpression)
{
    Expression&lt;Func&lt;ScheduleItemDto, bool&gt;&gt; notAdminExpression = x =&gt; x.Active
    return Expression.Lambda&lt;Func&lt;ScheduleItemDto, bool&gt;&gt;(Expression.AndAlso(baseExpression.Body, notAdminExpression.Body), baseExpression.Parameters[0]);
}
// ...
RestrictPermission(Where(...));




Now the ways I can think of rewriting the switch statement

If chain

if(closed == null &amp;&amp; eventGuid == null)
    return ...;
else if (closed == null &amp;&amp; eventGuid != null)
    return ...;
else if (closed &amp;&amp; eventGuid == null)
    return ...;
...


Very easy to parse which case each return belongs, but quite verbose.

Dictionary

 var options = new Dictionary&lt;Tuple&lt;bool?, bool&gt;, Expression&lt;Func&lt;ScheduleItemDto, bool&gt;&gt;&gt; {
    { Tuple.Create(null, true), baseExpression },
    { Tuple.Create(null, false), Expression.Lambda&lt;Func&lt;ScheduleItemDto, bool&gt;&gt;(Expression.AndAlso(baseExpression.Body, eventExpression.Body), baseExpression.Parameters[0]) },
    { Tuple.Create(true, true), Expression.Lambda&lt;Func&lt;ScheduleItemDto, bool&gt;&gt;(Expression.AndAlso(baseExpression.Body, closedExpression.Body), baseExpression.Parameters[0]) },
    // ...
}
return options[closed, eventGuid == null];


Adds complexity and reduces readability, but is probably the most compact version.

If plus ternary

if (closed == null)
    return eventGuid == null
        ? baseExpression 
        : Expression.Lambda&lt;Func&lt;ScheduleItemDto, bool&gt;&gt;(Expression.AndAlso(baseExpression.Body, closedExpression.Body), baseExpression.Parameters[0]);
else if (closed)
    ...
else
    ...


Half-way between readability and verbosity.



Honestly, I would stick to your switch or a chained-if. You can't get much elegance without making the code unnecessary complex. Or at least not with the options I know, I hope someone has a better solution.