I'm in the process of refactoring some code, attempting to make it more self-documenting. The current code has a query over an OData service which looks like this:
return context.MessageLog.Where
(
    x => 
    (
        x.Status == MessageStatus.Success 
        || x.Status == MessageStatus.Failure
    ) 
    && x.Direction == MessageDirection.Inbound 
    && x.ResponseDate == new DateTimeOffset(new DateTime(1900, 01, 01))
);
I'm hoping to change this to make use of Linq Expressions.
I could move all of the logic into a single expression and have code run context.MessageLog.Where(MessageIsPendingResponse);.
However, I'd like to create expressions for the different conditions: MessageIsProcessed (i.e. now at success or failure state), MessageIsInbound and ResponseNotYetSent (response date is null).
I could combine these with multiple where statements like so:
return context.MessageLog
    .Where(MessageLogExpression.MessageIsProcessed)
    .Where(MessageLogExpression.MessageIsInbound)
    .Where(MessageLogExpression.ResponseNotYetSent);
(MessageLogExpression being a class I use to contain these predefined expressions).
Question 1
Is this the best way to combine the satements, or does it risk filtering on the wrong field first (e.g. does Linq combine all the conditions into a single query and allow the query engine (in SQL terms) to determine the best execution plan; or are we forcing it to filter on the Status field first?
Question 2
The above is great for scenarios where we have an AND joining our expressions; but how would we do an OR?
I assume there's some way to combine these, but couldn't find anything obvious.  I suspect something like this exists?
return context.MessageLog.Where(new OrExpression(MessageIsSuccess,MessageIsFailure));
Question 3
Is there a good way to combine expressions within another expression defintion; e.g. something like the below code (only a version that compiles)?
public static Expression<Func<MessageLogRecord, bool>> MessageIsPendingResponse
{
    get
    {
        Expression<Func<MessageLogRecord, bool>> expr = x => 
            MessageIsProcessed(x) 
            && MessageIsInbound(x) 
            && ResponseNotYetSent(x);
        return expr;
    }
}
Addendum: Code for those expressions described above:
public class MessageLogExpression
{
    public static Expression<Func<MessageLogRecord, bool>> MessageIsProcessed
    {
        get
        {
            Expression<Func<MessageLogRecord, bool>> expr = x => 
            (
                x.Status == MessageStatus.Success 
                || x.Status == MessageStatus.Failure
            );
            return expr;
        }
    }
    public static Expression<Func<MessageLogRecord, bool>> MessageIsInbound
    {
        get
        {
            Expression<Func<MessageLogRecord, bool>> expr = x => 
                x.Direction == MessageDirection.Inbound;
            return expr;
        }
    }
    static readonly DateTimeOffset NullDate = new DateTimeOffset(new DateTime(1900, 01, 01));
    public static Expression<Func<MessageLogRecord, bool>> ResponseNotYetSent
    {
        get
        {
            Expression<Func<MessageLogRecord, bool>> expr = x => 
                x.ResponseDate == NullDate; //todo: test if this works or if I have to define the value within the expression
            return expr;
        }
    }
}
 
    