Ejemplo n.º 1
0
        //https://docs.oasis-open.org/odata/odata/v4.0/errata03/os/complete/part2-url-conventions/odata-v4.0-errata03-os-part2-url-conventions-complete.html#_Toc453752358
        private BinaryExpression CreateBinaryExpression(string equalityOperator, MemberExpression memberExpression, ConstantExpression constantExpression)
        {
            switch (equalityOperator)
            {
            case "eq":
                return(BinaryExpression.Equal(memberExpression, constantExpression));

            case "ne":
                return(BinaryExpression.NotEqual(memberExpression, constantExpression));

            case "gt":
                return(BinaryExpression.GreaterThan(memberExpression, constantExpression));

            case "lt":
                return(BinaryExpression.LessThan(memberExpression, constantExpression));

            case "ge":
                return(BinaryExpression.GreaterThanOrEqual(memberExpression, constantExpression));

            case "le":
                return(BinaryExpression.LessThanOrEqual(memberExpression, constantExpression));

            default:
                throw new System.Exception("Unnown equality operator");
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Visit Visual Basic Compare expression
        /// </summary>
        /// <param name="expression">Method call expression Compare expression</param>
        /// <param name="binExpNodeType">Binary expression node type</param>
        /// <returns>
        /// Reduced expression.
        /// </returns>
        protected virtual Expression VisitCompare(MethodCallExpression expression, ExpressionType binExpNodeType)
        {
            var left  = expression.Arguments[0];
            var right = expression.Arguments[1];

            switch (binExpNodeType)
            {
            case ExpressionType.Equal:
                return(BinaryExpression.Equal(left, right));

            case ExpressionType.NotEqual:
                return(BinaryExpression.NotEqual(left, right));

            case ExpressionType.LessThan:
                return(BinaryExpression.LessThan(left, right));

            case ExpressionType.LessThanOrEqual:
                return(BinaryExpression.LessThanOrEqual(left, right));

            case ExpressionType.GreaterThan:
                return(BinaryExpression.GreaterThan(left, right));

            case ExpressionType.GreaterThanOrEqual:
                return(BinaryExpression.GreaterThanOrEqual(left, right));
            }

            return(ThrowNotSupportedException(expression));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Add inner join.
        /// </summary>
        private void AddJoin <TSourceTable, TDestinationTable>(JoinType type, Expression <Func <TSourceTable, object> > sourceColumn,
                                                               Expression <Func <TDestinationTable, object> > destinationColumn)
        {
            if (sourceColumn == null)
            {
                throw new ArgumentNullException("sourceColumn");
            }
            if (destinationColumn == null)
            {
                throw new ArgumentNullException("destinationColumn");
            }
            Expression s, d;

            if (sourceColumn.Body is UnaryExpression)
            {
                s = sourceColumn.Body;
            }
            else
            {
                s = Expression.Constant(sourceColumn.Body);
            }
            if (destinationColumn.Body is UnaryExpression)
            {
                d = destinationColumn.Body;
            }
            else
            {
                d = Expression.Constant(destinationColumn.Body);
            }
            List.Add(new KeyValuePair <JoinType, BinaryExpression>(type, BinaryExpression.Equal(s, d)));
            Updated = true;
        }
Ejemplo n.º 4
0
        private BinaryExpression propertyEqualEqualConst(ParameterExpression atomParam, string property, object constVal)
        {
            var nameConstant = Expression.Constant(constVal);
            var nameMember   = MemberExpression.Property(atomParam as Expression, property);
            var equalExp     = BinaryExpression.Equal(nameMember, nameConstant);

            return(equalExp);
        }
Ejemplo n.º 5
0
        public void MakeBinaryWithOperandConversion_NoLifting()
        {
            var left  = Expression.Constant(0, typeof(int?));
            var right = Expression.Constant(0, typeof(int?));

            var result = ConversionUtility.MakeBinaryWithOperandConversion(ExpressionType.Equal, left, right, false, null);

            var expectedExpression = BinaryExpression.Equal(left, right);

            SqlExpressionTreeComparer.CheckAreEqualTrees(expectedExpression, result);
        }
Ejemplo n.º 6
0
        public void MakeBinaryWithOperandConversion_BothOperands_LiftedToObject()
        {
            var left  = Expression.Constant(null, typeof(string));
            var right = Expression.Constant(null, typeof(Cook));

            var result = ConversionUtility.MakeBinaryWithOperandConversion(ExpressionType.Equal, left, right, false, null);

            var expectedExpression = BinaryExpression.Equal(Expression.Convert(left, typeof(object)), Expression.Convert(right, typeof(object)));

            SqlExpressionTreeComparer.CheckAreEqualTrees(expectedExpression, result);
        }
Ejemplo n.º 7
0
            protected override Expression VisitMethodCall(MethodCallExpression node)
            {
                var stringType          = typeof(string);
                var typeInfo            = stringType.GetTypeInfo();
                var stringCompareMethod = typeInfo.GetMethods().Where(m => m == node.Method).FirstOrDefault();

                switch (stringCompareMethod.Name)
                {
                case "Equals":
                    return(VisitBinary(BinaryExpression.Equal(node.Arguments.First(), node.Arguments.Skip(1).First())));

                default:
                    throw new NotImplementedException(nameof(VisitMethodCall));
                }
                //return base.VisitMethodCall(node);
            }
        /// <summary>
        /// Checks if the binary expression is a string comparison emitted by the Visual Basic compiler.
        /// </summary>
        /// <remarks>The VB compiler translates string comparisons such as
        /// <code>(Function(x) x.Name = "a string value")</code> not as a binary expression with the field
        /// on the left side and the string value on the right side. Instead, it converts it into a call
        /// to <code>Microsoft.VisualBasic.CompilerServices.Operators.CompareString</code> (or
        /// <code>Microsoft.VisualBasic.CompilerServices.EmbeddedOperators</code> for phone platforms)
        /// for the string value, and compares the expression to zero.</remarks>
        /// <param name="expression">The binary expression to check.</param>
        /// <param name="stringComparison">A normalized string comparison expression.</param>
        /// <returns>True if the expression is a string comparison expression emitted by the VB compiler,
        /// otherwise false</returns>
        private bool CheckVBStringCompareExpression(BinaryExpression expression, out BinaryExpression stringComparison)
        {
            stringComparison = null;
            if (expression.Left.Type == typeofInt &&
                expression.Left.NodeType == ExpressionType.Call &&
                expression.Right.Type == typeofInt &&
                expression.Right.NodeType == ExpressionType.Constant &&
                ((ConstantExpression)expression.Right).Value.Equals(0))
            {
                MethodCallExpression methodCall = (MethodCallExpression)expression.Left;
                if ((methodCall.Method.DeclaringType.FullName == VBOperatorClass || methodCall.Method.DeclaringType.FullName == VBOperatorClassAlt) &&
                    methodCall.Method.Name == VBCompareStringMethod &&
                    methodCall.Arguments.Count == VBCompareStringArguments &&
                    methodCall.Arguments[VBCaseSensitiveCompareArgumentIndex].Type == typeof(bool) &&
                    methodCall.Arguments[VBCaseSensitiveCompareArgumentIndex].NodeType == ExpressionType.Constant)
                {
                    bool       doCaseInsensitiveComparison = ((ConstantExpression)methodCall.Arguments[VBCaseSensitiveCompareArgumentIndex]).Value.Equals(true);
                    Expression leftExpression  = methodCall.Arguments[0];
                    Expression rightExpression = methodCall.Arguments[1];
                    if (doCaseInsensitiveComparison)
                    {
                        leftExpression  = MethodCallExpression.Call(leftExpression, stringToLowerMethod);
                        rightExpression = MethodCallExpression.Call(rightExpression, stringToLowerMethod);
                    }

                    switch (expression.NodeType)
                    {
                    case ExpressionType.Equal:
                        stringComparison = BinaryExpression.Equal(leftExpression, rightExpression);
                        break;

                    case ExpressionType.NotEqual:
                        stringComparison = BinaryExpression.NotEqual(leftExpression, rightExpression);
                        break;

                    case ExpressionType.LessThan:
                        stringComparison = BinaryExpression.LessThan(leftExpression, rightExpression);
                        break;

                    case ExpressionType.LessThanOrEqual:
                        stringComparison = BinaryExpression.LessThanOrEqual(leftExpression, rightExpression);
                        break;

                    case ExpressionType.GreaterThan:
                        stringComparison = BinaryExpression.GreaterThan(leftExpression, rightExpression);
                        break;

                    case ExpressionType.GreaterThanOrEqual:
                        stringComparison = BinaryExpression.GreaterThanOrEqual(leftExpression, rightExpression);
                        break;
                    }

                    if (stringComparison != null)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
        protected override Expression VisitMethodCall(MethodCallExpression m)
        {
            if (m.Method.Name == "Where" || m.Method.Name == "First" || m.Method.Name == "FirstOrDefault")
            {
                var lambda = (LambdaExpression)StripQuotes(m.Arguments[1]);

                var solrQueryTranslator = new LinqToSolrQueryTranslator(_service);
                var fq = solrQueryTranslator.Translate(lambda.Body);
                sb.AppendFormat("&fq={0}", fq);

                var arr = StripQuotes(m.Arguments[0]);
                Visit(arr);
                return(m);
            }
            if (m.Method.Name == "Take")
            {
                var takeNumber = (int)((ConstantExpression)m.Arguments[1]).Value;
                _service.Configuration.Take = takeNumber;
                Visit(m.Arguments[0]);
                return(m);
            }
            if (m.Method.Name == "Skip")
            {
                var skipNumber = (int)((ConstantExpression)m.Arguments[1]).Value;
                _service.Configuration.Start = skipNumber;
                Visit(m.Arguments[0]);
                return(m);
            }


            if (m.Method.Name == "OrderBy" || m.Method.Name == "ThenBy")
            {
                var lambda = (LambdaExpression)StripQuotes(m.Arguments[1]);

                _service.CurrentQuery.AddSorting(lambda.Body, SolrSortTypes.Asc);

                Visit(m.Arguments[0]);

                return(m);
            }

            if (m.Method.Name == "OrderByDescending" || m.Method.Name == "ThenByDescending")
            {
                var lambda = (LambdaExpression)StripQuotes(m.Arguments[1]);
                _service.CurrentQuery.AddSorting(lambda.Body, SolrSortTypes.Desc);

                Visit(m.Arguments[0]);

                return(m);
            }



            if (m.Method.Name == "Select")
            {
                _service.CurrentQuery.Select = new LinqSolrSelect(StripQuotes(m.Arguments[1]));
                Visit(m.Arguments[0]);

                return(m);
            }


            if (m.Method.Name == "Contains")
            {
                if (m.Method.DeclaringType == typeof(string))
                {
                    var str = string.Format("*{0}*", ((ConstantExpression)StripQuotes(m.Arguments[0])).Value);


                    Visit(BinaryExpression.Equal(m.Object, ConstantExpression.Constant(str)));

                    return(m);
                }
                else
                {
                    var        arr = (ConstantExpression)StripQuotes(m.Arguments[0]);
                    Expression lambda;

                    if (m.Arguments.Count == 2)
                    {
                        lambda = StripQuotes(m.Arguments[1]);
                        Visit(lambda);
                        Visit(arr);
                    }
                    else
                    {
                        var newExpr = Expression.Equal(m.Object, m.Arguments[0]);
                        var expr    = new LinqToSolrQueryTranslator(_service, m.Arguments[0].Type);
                        expr.IsMultiList = true;
                        var multilistfq = expr.Translate(newExpr);
                        sb.AppendFormat("{0}", multilistfq);
                    }


                    return(m);
                }
            }

            if (m.Method.Name == "StartsWith")
            {
                if (m.Method.DeclaringType == typeof(string))
                {
                    var str = string.Format("{0}*", ((ConstantExpression)StripQuotes(m.Arguments[0])).Value);
                    Visit(BinaryExpression.Equal(m.Object, ConstantExpression.Constant(str)));

                    return(m);
                }
            }
            if (m.Method.Name == "EndsWith")
            {
                if (m.Method.DeclaringType == typeof(string))
                {
                    var str = string.Format("*{0}", ((ConstantExpression)StripQuotes(m.Arguments[0])).Value);
                    Visit(BinaryExpression.Equal(m.Object, ConstantExpression.Constant(str)));

                    return(m);
                }
            }

            if (m.Method.Name == "GroupBy")
            {
                _service.CurrentQuery.IsGroupEnabled = true;
                var arr = StripQuotes(m.Arguments[1]);
#if PORTABLE || NETCORE
                var solrQueryTranslator =
                    new LinqToSolrQueryTranslator(_service, ((MemberExpression)((LambdaExpression)arr).Body).Member.DeclaringType);
#else
                var solrQueryTranslator = new LinqToSolrQueryTranslator(_service,
                                                                        ((MemberExpression)((LambdaExpression)arr).Body).Member.ReflectedType);
#endif

                _service.CurrentQuery.GroupFields.Add(solrQueryTranslator.Translate(arr));
                Visit(m.Arguments[0]);

                return(m);

                //throw new Exception("The method 'GroupBy' is not supported in Solr. For native FACETS support use SolrQuaryableExtensions.GroupBySolr instead.");
            }

            throw new NotSupportedException(string.Format("The method '{0}' is not supported", m.Method.Name));
        }
        public object CreateBusinessQueryExpression(IList <SearchingArgument> SearchingArguments)
        {
            Expression <Func <Business, bool> > expression = b => (true);

            if (SearchingArguments != null && SearchingArguments.Count > 0)
            {
                ParameterExpression parameter = Expression.Parameter(typeof(Business), "b");

                MemberExpression member;

                ConstantExpression value = Expression.Constant(1);

                Expression body = BinaryExpression.Equal(value, value);

                Expression predicate = body;

                foreach (var arg in SearchingArguments)
                {
                    member = Expression.Property(parameter, arg.FieldName);
                    value  = Expression.Constant(arg.FieldValue);

                    switch (arg.Operator)
                    {
                    case OperatorEnum.EqualTo:
                        body = BinaryExpression.Equal(member, value);
                        break;

                    case OperatorEnum.NotEqualTo:
                        body = BinaryExpression.NotEqual(member, value);
                        break;

                    case OperatorEnum.GreaterThan:
                        body = BinaryExpression.GreaterThan(member, value);
                        break;

                    case OperatorEnum.GreaterThanOrEqualTo:
                        body = BinaryExpression.GreaterThanOrEqual(member, value);
                        break;

                    case OperatorEnum.In:
                        body = Expression.Call(value, value.Type.GetInterface("ICollection`1").GetMethod("Contains"), member);
                        break;

                    case OperatorEnum.NotIn:
                        body = BinaryExpression.Not(Expression.Call(value, value.Type.GetInterface("ICollection`1").GetMethod("Contains"), member));
                        break;

                    case OperatorEnum.Is:
                        break;

                    case OperatorEnum.IsNot:
                        break;

                    case OperatorEnum.LessThan:
                        body = BinaryExpression.LessThan(member, value);
                        break;

                    case OperatorEnum.LessThanOrEqualTo:
                        body = BinaryExpression.LessThanOrEqual(member, value);
                        break;

                    case OperatorEnum.StartsWith:
                        body = Expression.Call(member, typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }), value);
                        break;

                    case OperatorEnum.NotStartWith:
                        body = BinaryExpression.Not(Expression.Call(member, typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) }), value));
                        break;

                    case OperatorEnum.EndsWith:
                        body = Expression.Call(member, typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) }), value);
                        break;

                    case OperatorEnum.NotEndWith:
                        body = BinaryExpression.Not(Expression.Call(member, typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) }), value));
                        break;

                    case OperatorEnum.Includes:
                        body = Expression.Call(member, member.Type.GetMethod("Contains"), value);
                        break;

                    case OperatorEnum.NotInclude:
                        body = BinaryExpression.Not(Expression.Call(member, member.Type.GetMethod("Contains"), value));
                        break;

                    default:
                        break;
                    }

                    predicate = arg.LogicalOperator == LogicalOperatorEnum.And ? BinaryExpression.And(predicate, body) : BinaryExpression.Or(predicate, body);
                }

                expression = Expression.Lambda <Func <Business, bool> >(predicate, parameter);
            }

            return(expression);
        }
        public void GetIndexEvents_ExpressionTree()
        {
            using (var db = Helper.CreatePCORIDataContext(ConnectionString))
            {
                ParameterExpression pe_proQueryType            = ParameterExpression.Parameter(typeof(PCORIQueryBuilder.Model.ReportedOutcome), "pro");
                ParameterExpression pe_clinicalTrialsQueryType = ParameterExpression.Parameter(typeof(ClinicalTrial), "tr");
                ConstantExpression  ce_daysBefore  = ConstantExpression.Constant(0f, typeof(float));
                ConstantExpression  ce_daysAfter   = ConstantExpression.Constant(300f, typeof(float));
                ConstantExpression  ce_proItemName = ConstantExpression.Constant("HOSPITALIZATION_DATE", typeof(string));
                ConstantExpression  ce_trialID     = ConstantExpression.Constant("FAKE_TRIAL-15", typeof(string));


                var outerSelector = Expression.Lambda(Expression.Property(pe_proQueryType, "PatientID"), pe_proQueryType);
                var innerSelector = Expression.Lambda(Expression.Property(pe_clinicalTrialsQueryType, "PatientID"), pe_clinicalTrialsQueryType);

                Type joinResultType = Objects.Dynamic.TypeBuilderHelper.CreateType("IndexEvents", new[] {
                    new DTO.QueryComposer.QueryComposerResponsePropertyDefinitionDTO {
                        Name = "PRO_ID", Type = "System.String"
                    },
                    new DTO.QueryComposer.QueryComposerResponsePropertyDefinitionDTO {
                        Name = "PatientID", Type = "System.String"
                    },
                    new DTO.QueryComposer.QueryComposerResponsePropertyDefinitionDTO {
                        Name = "ItemName", Type = "System.String"
                    },
                    new DTO.QueryComposer.QueryComposerResponsePropertyDefinitionDTO {
                        Name = "ResponseText", Type = "System.String"
                    },
                    new DTO.QueryComposer.QueryComposerResponsePropertyDefinitionDTO {
                        Name = "ResponseNumber", Type = typeof(double?).ToString()
                    },
                    new DTO.QueryComposer.QueryComposerResponsePropertyDefinitionDTO {
                        Name = "ResponseSequence", Type = "System.String"
                    },
                    new DTO.QueryComposer.QueryComposerResponsePropertyDefinitionDTO {
                        Name = "ParticipantID", Type = "System.String"
                    },
                    new DTO.QueryComposer.QueryComposerResponsePropertyDefinitionDTO {
                        Name = "TrialID", Type = "System.String"
                    },
                    new DTO.QueryComposer.QueryComposerResponsePropertyDefinitionDTO {
                        Name = "TimeWindowAfter", Type = typeof(float).ToString()
                    },
                    new DTO.QueryComposer.QueryComposerResponsePropertyDefinitionDTO {
                        Name = "TimeWindowBefore", Type = typeof(float).ToString()
                    }
                });

                IEnumerable <MemberBinding> joinBindings = new[] {
                    Expression.Bind(joinResultType.GetProperty("PRO_ID"), Expression.Property(pe_proQueryType, pe_proQueryType.Type.GetProperty("ID"))),
                    Expression.Bind(joinResultType.GetProperty("PatientID"), Expression.Property(pe_proQueryType, pe_proQueryType.Type.GetProperty("PatientID"))),
                    Expression.Bind(joinResultType.GetProperty("ItemName"), Expression.Property(pe_proQueryType, pe_proQueryType.Type.GetProperty("ItemName"))),
                    Expression.Bind(joinResultType.GetProperty("ResponseText"), Expression.Property(pe_proQueryType, pe_proQueryType.Type.GetProperty("ResponseText"))),
                    Expression.Bind(joinResultType.GetProperty("ResponseNumber"), Expression.Property(pe_proQueryType, pe_proQueryType.Type.GetProperty("ResponseNumber"))),
                    Expression.Bind(joinResultType.GetProperty("ResponseSequence"), Expression.Property(pe_proQueryType, pe_proQueryType.Type.GetProperty("MeasureSequence"))),
                    Expression.Bind(joinResultType.GetProperty("ParticipantID"), Expression.Property(pe_clinicalTrialsQueryType, pe_clinicalTrialsQueryType.Type.GetProperty("ParticipantID"))),
                    Expression.Bind(joinResultType.GetProperty("TrialID"), Expression.Property(pe_clinicalTrialsQueryType, pe_clinicalTrialsQueryType.Type.GetProperty("TrialID"))),
                    Expression.Bind(joinResultType.GetProperty("TimeWindowAfter"), Expression.Add(Expression.Convert(Expression.Property(pe_proQueryType, pe_proQueryType.Type.GetProperty("ResponseNumber")), typeof(float)), ce_daysAfter)),
                    Expression.Bind(joinResultType.GetProperty("TimeWindowBefore"), Expression.Subtract(Expression.Convert(Expression.Property(pe_proQueryType, pe_proQueryType.Type.GetProperty("ResponseNumber")), typeof(float)), ce_daysBefore))
                };

                var pe_joinType = ParameterExpression.Parameter(joinResultType, "j");

                var resultSelector = Expression.Lambda(
                    Expression.MemberInit(Expression.New(joinResultType), joinBindings),
                    pe_proQueryType,
                    pe_clinicalTrialsQueryType
                    );

                MethodCallExpression joinCall = Expression.Call(
                    typeof(Queryable),
                    "Join",
                    new Type[] {
                    typeof(ReportedOutcome), //outer
                    typeof(ClinicalTrial),   //inner
                    typeof(string),          //key
                    joinResultType
                },
                    new Expression[] {
                    db.ReportedOutcomeCommonMeasures.AsQueryable().Expression,
                    db.ClinicalTrials.AsQueryable().Expression,
                    Expression.Quote(outerSelector),
                    Expression.Quote(innerSelector),
                    Expression.Quote(resultSelector)
                }
                    );

                BinaryExpression itemNameExprs           = BinaryExpression.Equal(Expression.Property(pe_joinType, "ItemName"), ce_proItemName);
                BinaryExpression trialIDExprs            = Expression.Equal(Expression.Property(pe_joinType, "TrialID"), ce_trialID);
                BinaryExpression requireResponseNumExprs = Expression.NotEqual(Expression.Property(pe_joinType, "ResponseNumber"), Expression.Constant(null));

                BinaryExpression predicate = Expression.AndAlso(Expression.AndAlso(itemNameExprs, trialIDExprs), requireResponseNumExprs);

                var whereCall = Expression.Call(typeof(Queryable), "Where", new[] { joinResultType }, joinCall, Expression.Quote(Expression.Lambda(predicate, pe_joinType)));

                var query = db.ReportedOutcomeCommonMeasures.AsQueryable().Provider.CreateQuery(whereCall);
                Logger.Debug(query.Expression);

                Logger.Debug(query.ToTraceQuery());
            }


            //left outer join on procedures where procedure ID is null (omit procedures), use group join
            //https://docs.microsoft.com/en-us/dotnet/csharp/linq/perform-left-outer-joins
        }