Tag Archives: linq

Linq Expression larını birleştirmek

Bu yazıda DataSourceRequest nesnesi ile kendi yazdığımız bir linq expression ı nasıl birleştireceğimizi anlatacağım. Bu işlemi bir .net sınıfı olan ExpressionVisitor sınıfı ile yapacağız. Kullanacağımız custom ExpressionVisitor şu şekilde

class ParameterUpdateVisitor : ExpressionVisitor
    {
        private ParameterExpression _oldParameter;
        private ParameterExpression _newParameter;

        public ParameterUpdateVisitor(ParameterExpression oldParameter, ParameterExpression newParameter)
        {
            _oldParameter = oldParameter;
            _newParameter = newParameter;
        }

        protected override Expression VisitParameter(ParameterExpression node)
        {
            if (object.ReferenceEquals(node, _oldParameter))
                return _newParameter;

            return base.VisitParameter(node);
        }
        public static Expression<Func<T, bool>> UpdateParameter<T>(Expression<Func<T, bool>> expr,ParameterExpression newParameter)
        {
            var visitor = new ParameterUpdateVisitor(expr.Parameters[0], newParameter);
            var body = visitor.Visit(expr.Body);

            return Expression.Lambda<Func<T, bool>>(body, newParameter);
        }
    }
public Expression<Func<VType, bool>> KendoFilterExpression(DataSourceRequest req, Expression<Func<VType, bool>> predToJoin = null)
        {
            var str = "";
            if (req != null && req.Filter != null && req.Filter.Filters.Count() > 0)
            {
                str = req.Filter.ToExpressionMy(req.Filter.Filters.ToList(), CaseInSensitive);
                var dataVal = req.Filter.Filters.Select(a => (CaseInSensitive && a.Value.GetType() == "".GetType()) ? a.Value.ToString().ToUpperInvariant() : a.Value).ToArray();
                var kendoExp = System.Linq.Dynamic.DynamicExpression.ParseLambda<VType, bool>(str, dataVal);

                if (predToJoin != null)
                {
                    // linq içindeki parametreyi (a=> deki a) birleştireceğimiz expression ın parametresi ile aynı yapıyoruz
                    kendoExp = ParameterUpdateVisitor.UpdateParameter<VType>(kendoExp, predToJoin.Parameters.Single());
                    var e = Expression.Lambda<Func<VType, bool>>(Expression.And(predToJoin.Body, kendoExp.Body), kendoExp.Parameters);
                    return e;
                }
                else
                    return kendoExp;
            }
            else
            {
                if (predToJoin != null)
                    return predToJoin;
                else
                    return null;
            }
        }