using System;
using System.Linq;
using System.Linq.Expressions;
namespace Hncore.Infrastructure.EntitiesExtension
{
///
/// Extension methods for add And and Or with parameters rebinder
///
public static class ExpressionBuilder
{
///
/// Compose two expression and merge all in a new expression
///
/// Type of params in expression
/// Expression instance
/// Expression to merge
/// Function to merge
/// New merged expressions
public static Expression Compose(this Expression first, Expression second, Func merge)
{
// build parameter map (from parameters of second to parameters of first)
var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
// replace parameters in the second lambda expression with parameters from the first
var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
// apply composition of lambda expression bodies to parameters from the first expression
return Expression.Lambda(merge(first.Body, secondBody), first.Parameters);
}
///
/// And operator
///
/// Type of params in expression
/// Right Expression in AND operation
/// Left Expression in And operation
/// New AND expression
public static Expression> And(this Expression> first, Expression> second)
{
return first.Compose(second, Expression.AndAlso);
}
///
/// Or operator
///
/// Type of param in expression
/// Right expression in OR operation
/// Left expression in OR operation
/// New Or expressions
public static Expression> Or(this Expression> first, Expression> second)
{
return first.Compose(second, Expression.Or);
}
}
}