//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"); } }
/// <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)); }
/// <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; }
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); }
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); }
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); }
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 }