构建动态linq查询,并为集合

时间:2015-12-01 09:32:15

标签: c# linq

我有一个像这样生成lambda表达式的函数

d => d.Defendeurs.Any(DossierTiers => DossierTiers.Tiers.TiersLiesEnfantsActifs.Any(TiersLie => TiersLie.TiersEnfant.AdressePrincipale.Adresse.CodePostal.Contains("45")))

所有工作但有时我在某些类上获得了NullExceptionReference。 所以我需要检查一些属性是否为null。 我想,我必须在BuildLambda函数中添加一些代码,但我的所有测试都不起作用。 欢迎提供一些帮助

       public static Expression GetExpression(Expression parameter, object Operator, object value, params string[] properties)
        {
            Expression resultExpression = null;
            Expression childParameter, navigationPropertyPredicate;
            Type childType = null;

            if (properties.Count() > 1)
            {
                parameter = Expression.Property(parameter, properties[0]);
                var isCollection = typeof(IEnumerable).IsAssignableFrom(parameter.Type);
                if (isCollection)
                {
                    childType = parameter.Type.GetGenericArguments()[0];
                    childParameter = Expression.Parameter(childType, childType.Name);
                }
                else
                {
                    childParameter = parameter;
                }
                var innerProperties = properties.Skip(1).ToArray();
                navigationPropertyPredicate = GetExpression(childParameter, Operator, value, innerProperties);
                if (isCollection)
                {
                    var anyMethod = typeof(Enumerable).GetMethods().Single(m => m.Name == "Any" && m.GetParameters().Length == 2);
                    anyMethod = anyMethod.MakeGenericMethod(childType);
                    navigationPropertyPredicate = Expression.Call(anyMethod, parameter, navigationPropertyPredicate);
                    resultExpression = BuildLambda(parameter, navigationPropertyPredicate);
                }
                else
                {
                    resultExpression = navigationPropertyPredicate;
                }
            }
            else
            {
                ConstantExpression right = null;
                var childProperty = parameter.Type.GetProperty(properties[0]);
                var left = Expression.Property(parameter, childProperty);
                right = (value != null) ? right = Expression.Constant(value, value.GetType()) : Expression.Constant(string.Empty);
                navigationPropertyPredicate = GetExpression(left, right, Operator);
                resultExpression = BuildLambda(parameter, navigationPropertyPredicate);
            }
            return resultExpression;
        }

        private static Expression BuildLambda(Expression parameter, Expression predicate)
        {
            var resultParameterVisitor = new ParameterVisitor();
            resultParameterVisitor.Visit(parameter);
            var resultParameter = resultParameterVisitor.Parameter;
            return Expression.Lambda(predicate, (ParameterExpression)resultParameter);
        }

       private static Expression GetExpression(MemberExpression left, ConstantExpression right, Object p)
        {
            MethodInfo c = null;
            if (p is OperatorUsedWithString)
            {
                switch ((OperatorUsedWithString)p)
                {
                    case OperatorUsedWithString.CommencePar:
                        c = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) });
                        return Expression.Call(left, c, right);
                    case OperatorUsedWithString.Contient:
                        c = typeof(string).GetMethod("Contains", new Type[] { typeof(string) });
                        return Expression.Call(left, c, right);
                    case OperatorUsedWithString.TerminePar:
                        c = typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) });
                        return Expression.Call(left, c, right);
                    case OperatorUsedWithString.Egal:
                        c = typeof(string).GetMethod("Equals", new Type[] { typeof(string) });
                        return Expression.Call(left, c, right);

                }
            }
            if (p is OperatorUsedWithNumber)
            {
                switch ((OperatorUsedWithNumber)p)
                {
                    case OperatorUsedWithNumber.Egal:
                        return Expression.Equal(left, right);
                    case OperatorUsedWithNumber.Inferieur:
                        return Expression.LessThan(left, right);
                    case OperatorUsedWithNumber.InferieurEgal:
                        return Expression.LessThanOrEqual(left, right);
                    case OperatorUsedWithNumber.Superieur:
                        return Expression.GreaterThan(left, right);
                    case OperatorUsedWithNumber.SuperieurEgal:
                        return Expression.GreaterThanOrEqual(left, right);



                }
            }
            if (p is OperatorUsedWithDateTime)
            {
                switch ((OperatorUsedWithDateTime)p)
                {
                    case OperatorUsedWithDateTime.PasPresent:
                        return Expression.Equal(left, Expression.Constant(null));
                    case OperatorUsedWithDateTime.Present:
                        return Expression.NotEqual(left, Expression.Constant(null));
                }


            }
            throw new NotImplementedException();
        }
    }

0 个答案:

没有答案