private void ParseNode <TKey, TAggregateRoot>(ParseTreeNode node, ref SortSpecification <TKey, TAggregateRoot> sortSpecification) where TKey : IEquatable <TKey> where TAggregateRoot : class, IAggregateRoot <TKey> { switch (node.Term.Name) { case "sort-specification": var suggestedPropertyName = node.ChildNodes[0].ChildNodes[0].Token.ValueString; var suggestedSortingOrder = node.ChildNodes[1].ChildNodes[0].Token.ValueString; var propertyName = ParsingUtils.InferProperty <TAggregateRoot>(suggestedPropertyName)?.Name; if (string.IsNullOrEmpty(propertyName)) { throw new ParsingException("Expression parsed failed.", new[] { $"The property that has the name similar to {suggestedPropertyName} does not exist." }); } var sortOrder = suggestedSortingOrder.ToUpper() == "A" ? SortOrder.Ascending : SortOrder.Descending; sortSpecification.Add(propertyName, sortOrder); break; case "concatenated-sort-specification": var leftNode = node.ChildNodes[0]; var rightNode = node.ChildNodes[2]; ParseNode(leftNode, ref sortSpecification); ParseNode(rightNode, ref sortSpecification); break; } }
private Expression ParseExpression <T>(ParseTreeNode node, ParameterExpression parameterExpression) { switch (node.Term.Name) { case "logical-operation": var leftLogicalOperandNode = node.ChildNodes[0]; var logicalOperatorNode = node.ChildNodes[1]; var rightLogicalOprandNode = node.ChildNodes[2]; switch (logicalOperatorNode.ChildNodes[0].Term.Name) { case "AND": return(Expression.AndAlso(ParseExpression <T>(leftLogicalOperandNode, parameterExpression), ParseExpression <T>(rightLogicalOprandNode, parameterExpression))); case "OR": return(Expression.OrElse(ParseExpression <T>(leftLogicalOperandNode, parameterExpression), ParseExpression <T>(rightLogicalOprandNode, parameterExpression))); } break; case "relational-operation": var leftRelationalOperandNode = node.ChildNodes[0]; var relationalOperatorNode = node.ChildNodes[1]; var rightRelationalOperandNode = node.ChildNodes[2]; var leftExpression = ParseExpression <T>(leftRelationalOperandNode, parameterExpression); var rightExpression = ParseExpression <T>(rightRelationalOperandNode, parameterExpression); if (leftExpression.NodeType == ExpressionType.Constant || rightExpression.NodeType == ExpressionType.Constant) { FixExpressionType(ref leftExpression, ref rightExpression); } switch (relationalOperatorNode.ChildNodes[0].Term.Name) { case "EQ": return(Expression.Equal(leftExpression, rightExpression)); case "NE": return(Expression.NotEqual(leftExpression, rightExpression)); case "GE": return(Expression.GreaterThanOrEqual(leftExpression, rightExpression)); case "GT": return(Expression.GreaterThan(leftExpression, rightExpression)); case "LE": return(Expression.LessThanOrEqual(leftExpression, rightExpression)); case "LT": return(Expression.LessThan(leftExpression, rightExpression)); } break; case "not-operation": return(Expression.Not(ParseExpression <T>(node.ChildNodes[1], parameterExpression))); case "string-operation": var leftStringFunctionOperandNode = node.ChildNodes[0]; var stringFunctionNode = node.ChildNodes[1]; var rightStringFunctionOperandNode = node.ChildNodes[2]; var leftStringFunctionExpression = ParseExpression <T>(leftStringFunctionOperandNode, parameterExpression); var rightStringFunctionExpression = ParseExpression <T>(rightStringFunctionOperandNode, parameterExpression); switch (stringFunctionNode.ChildNodes[0].Term.Name) { case "SW": return(Expression.Call(leftStringFunctionExpression, typeof(string).GetMethod("StartsWith", new[] { typeof(string) }), rightStringFunctionExpression)); case "EW": return(Expression.Call(leftStringFunctionExpression, typeof(string).GetMethod("EndsWith", new[] { typeof(string) }), rightStringFunctionExpression)); case "CT": return(Expression.Call(leftStringFunctionExpression, typeof(string).GetMethod("Contains"), rightStringFunctionExpression)); } break; case "property": var inferredProperty = ParsingUtils.InferProperty <T>(node.ChildNodes[0].Token.ValueString); if (inferredProperty == null) { throw new ParsingException("Expression parsed failed.", new[] { $"The property that has the name similar to {node.ChildNodes[0].Token.ValueString} does not exist." }); } var propertyName = ParsingUtils.InferProperty <T>(node.ChildNodes[0].Token.ValueString).Name; return(Expression.Property(parameterExpression, node.ChildNodes[0].Token.ValueString)); case "string": return(Expression.Constant(node.Token.Value)); case "number": var expr = Expression.Constant(node.Token.Value); return(expr); } return(null); }