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));
        }
Esempio n. 2
0
        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));
        }