public static Expression <TDelegate> ComposePredicate <TDelegate>(List <LambdaExpression> filterPredicates, Expression[] expressionSubstitutes, ParameterExpression parameter) { Expression predicateBody = null; foreach (LambdaExpression filterPredicate in filterPredicates) { var body = JoinQueryParameterExpressionReplacer.Replace(filterPredicate, expressionSubstitutes, parameter).Body; if (predicateBody == null) { predicateBody = body; } else { predicateBody = Expression.AndAlso(predicateBody, body); } } Expression <TDelegate> predicate = Expression.Lambda <TDelegate>(predicateBody, parameter); return(predicate); }
public IQuery <TResult> Select <TResult>(Expression <Func <T1, T2, TResult> > selector) { if (this._filterPredicates.Count == 0) { JoinQueryExpression e1 = new JoinQueryExpression(typeof(TResult), this._rootQuery.QueryExpression, this._joinedQueries, selector); return(new Query <TResult>(this.DbContext, e1, this._rootQuery.TrackEntity)); } /* * q.LeftJoin<City>((user, city) => user.CityId == city.Id).Where((user, city) => user.Name == "lu").Select((user, city) => new { user, city }) * 转换成: * q.LeftJoin<City>((user, city) => user.CityId == city.Id) * .Select((user, city) => new JoinResult<T1, T2>() { Item1 = user, Item2 = city }) * .Where(a => a.Item1.Name == "lu") * .Select(a => new { user = a.user, city = a.city }) */ Type joinResultType = typeof(JoinResult <T1, T2>); Expression <Func <T1, T2, JoinResult <T1, T2> > > joinResultSelector = (t1, t2) => new JoinResult <T1, T2>() { Item1 = t1, Item2 = t2 }; JoinQueryExpression e = new JoinQueryExpression(joinResultType, this._rootQuery.QueryExpression, this._joinedQueries, joinResultSelector); IQuery <JoinResult <T1, T2> > q = new Query <JoinResult <T1, T2> >(this.DbContext, e, this._rootQuery.TrackEntity); ParameterExpression parameter = Expression.Parameter(joinResultType, "a"); Expression[] expressionSubstitutes = QueryHelper.MakeExpressionSubstitutes(joinResultType, parameter); Expression <Func <JoinResult <T1, T2>, bool> > predicate = QueryHelper.ComposePredicate <Func <JoinResult <T1, T2>, bool> >(this._filterPredicates, expressionSubstitutes, parameter); var q1 = q.Where(predicate); Expression <Func <JoinResult <T1, T2>, TResult> > selector2 = JoinQueryParameterExpressionReplacer.Replace(selector, expressionSubstitutes, parameter) as Expression <Func <JoinResult <T1, T2>, TResult> >; var ret = q1.Select(selector2); return(ret); }