public IQueryable <TDerivedEntity> SatisfiedBy <TDerivedEntity>(IQueryable <TDerivedEntity> entities) where TDerivedEntity : TEntity { if (entities == null) { throw new ArgumentNullException(nameof(entities)); } var entityPredicate = Predicate; if (entityPredicate == null) { throw new InvalidOperationException("Predicate"); } if (typeof(TDerivedEntity) == typeof(TEntity)) { return((IQueryable <TDerivedEntity>)((IQueryable <TEntity>)entities).Where(entityPredicate)); } var entityParameter = entityPredicate.Parameters.Single(); var derivedEntityParameter = Expression.Parameter(typeof(TDerivedEntity), entityParameter.Name); var parameterVisitor = new ParameterVisitor(entityParameter, derivedEntityParameter); var derivedEntityBody = parameterVisitor.Visit(entityPredicate.Body); var derivedEntityExpression = Expression.Lambda(derivedEntityBody, derivedEntityParameter); return(entities.Where((Expression <Func <TDerivedEntity, bool> >)derivedEntityExpression)); }
private static Expression <Func <TDerivedEntity, bool> > Compose <TEntity, TDerivedEntity>( this Expression <Func <TEntity, bool> > firstExpression, Expression <Func <TDerivedEntity, bool> > secondExpression, Func <Expression, Expression, Expression> mergeFunc) where TDerivedEntity : TEntity { var derivedParameter = Expression.Parameter(typeof(TDerivedEntity)); var firstParameter = firstExpression.Parameters.Single(); var firstParameterVisitor = new ParameterVisitor(firstParameter, derivedParameter); var firstBody = firstParameterVisitor.Visit(firstExpression.Body); var secondParameter = secondExpression.Parameters.Single(); var secondParameterVisitor = new ParameterVisitor(secondParameter, derivedParameter); var secondBody = secondParameterVisitor.Visit(secondExpression.Body); return(Expression.Lambda <Func <TDerivedEntity, bool> >( mergeFunc(firstBody, secondBody), derivedParameter)); }