public override void VisitJoinClause(Remotion.Linq.Clauses.JoinClause joinClause, QueryModel queryModel, int index) { _isInstanceQuery = false; _queryBuilder.AddFromPart(joinClause); var inner = SparqlGeneratorWhereExpressionTreeVisitor.GetSparqlExpression(joinClause.InnerKeySelector, _queryBuilder); var outer = SparqlGeneratorWhereExpressionTreeVisitor.GetSparqlExpression(joinClause.OuterKeySelector, _queryBuilder); if (inner is SelectVariableNameExpression && outer is SelectVariableNameExpression) { var innerVar = inner as SelectVariableNameExpression; var outerVar = outer as SelectVariableNameExpression; if (innerVar.BindingType == VariableBindingType.Literal || outerVar.BindingType == VariableBindingType.Literal) { _queryBuilder.AddFilterExpression(string.Format("(?{0}=?{1})", innerVar.Name, outerVar.Name)); } else { _queryBuilder.AddFilterExpression(string.Format("(sameTerm(?{0}, ?{1}))", innerVar.Name, outerVar.Name)); } } else { throw new NotSupportedException( String.Format("No support for joining expressions of type {0} and {1}", inner.NodeType, outer.NodeType)); } }
public static Expression GetSparqlExpression(Expression expression, SparqlQueryBuilder queryBuilder) { var visitor = new SparqlGeneratorWhereExpressionTreeVisitor(queryBuilder); var returnedExpression = visitor.VisitExpression(expression); if (returnedExpression is SelectVariableNameExpression && expression.Type.Equals(typeof(bool))) { var svn = (SelectVariableNameExpression)returnedExpression; // Single boolean member expression requires a special case addition to the filter queryBuilder.AddFilterExpression("(?" + svn.Name + " = true)"); } queryBuilder.AddFilterExpression(visitor.FilterExpression); return(returnedExpression); }
private string GetExpressionVariable(Expression expression) { if (expression is QuerySourceReferenceExpression) { var querySource = expression as QuerySourceReferenceExpression; Expression mappedExpression; _queryBuilder.TryGetQuerySourceMapping(querySource.ReferencedQuerySource, out mappedExpression); if (mappedExpression is SelectVariableNameExpression) return (mappedExpression as SelectVariableNameExpression).Name; } var selector = SparqlGeneratorWhereExpressionTreeVisitor.GetSparqlExpression(expression, _queryBuilder); if (selector is SelectVariableNameExpression) return (selector as SelectVariableNameExpression).Name; return null; }
public static Expression GetSparqlExpression(Expression expression, SparqlQueryBuilder queryBuilder, bool filterOptimizationEnabled) { var canOptimizeFilter = filterOptimizationEnabled && CanOptimizeFilter(expression, queryBuilder); var visitor = new SparqlGeneratorWhereExpressionTreeVisitor(queryBuilder, canOptimizeFilter, expression.Type == typeof(bool)); var returnedExpression = visitor.VisitExpression(expression); var svn = returnedExpression as SelectVariableNameExpression; if (svn != null && expression.Type == typeof(bool)) { // Single boolean member expression requires a special case addition to the filter queryBuilder.AddFilterExpression("(?" + svn.Name + " = true)"); } queryBuilder.AddFilterExpression(visitor.FilterExpression); return(returnedExpression); }
public override void VisitAdditionalFromClause(Remotion.Linq.Clauses.AdditionalFromClause fromClause, QueryModel queryModel, int index) { _isInstanceQuery = false; var fromVar = _queryBuilder.AddFromPart(fromClause); if (!(fromClause.FromExpression is ConstantExpression)) { var fromExpression = SparqlGeneratorWhereExpressionTreeVisitor.GetSparqlExpression(fromClause.FromExpression, _queryBuilder); if (fromExpression is SelectVariableNameExpression) { _queryBuilder.RenameVariable((fromExpression as SelectVariableNameExpression).Name,fromVar); } } base.VisitAdditionalFromClause(fromClause, queryModel, index); }
public override void VisitOrdering(Remotion.Linq.Clauses.Ordering ordering, QueryModel queryModel, Remotion.Linq.Clauses.OrderByClause orderByClause, int index) { _isInstanceQuery = false; var selector = SparqlGeneratorWhereExpressionTreeVisitor.GetSparqlExpression(ordering.Expression, _queryBuilder); if (selector is SelectVariableNameExpression) { var selectorVar = selector as SelectVariableNameExpression; _queryBuilder.AddOrdering(new SparqlOrdering("?" + selectorVar.Name, ordering.OrderingDirection)); } else { throw new NotSupportedException( String.Format("LINQ-to-SPARQL does not currently support ordering by the expression '{0}'", ordering.Expression)); } base.VisitOrdering(ordering, queryModel, orderByClause, index); }
private string GetExpressionVariable(Expression expression) { if (expression is QuerySourceReferenceExpression) { var querySource = expression as QuerySourceReferenceExpression; Expression mappedExpression; _queryBuilder.TryGetQuerySourceMapping(querySource.ReferencedQuerySource, out mappedExpression); if (mappedExpression is SelectVariableNameExpression) { return((mappedExpression as SelectVariableNameExpression).Name); } } var selector = SparqlGeneratorWhereExpressionTreeVisitor.GetSparqlExpression(expression, _queryBuilder, _context.FilterOptimizationEnabled); if (selector is SelectVariableNameExpression) { return((selector as SelectVariableNameExpression).Name); } return(null); }
public override void VisitWhereClause(Remotion.Linq.Clauses.WhereClause whereClause, QueryModel queryModel, int index) { SparqlGeneratorWhereExpressionTreeVisitor.GetSparqlExpression(whereClause.Predicate, _queryBuilder); base.VisitWhereClause(whereClause, queryModel, index); }
protected override Expression VisitMethodCallExpression(MethodCallExpression expression) { if (expression.Method.Name.Equals("Equals")) { if (QueryBuilder.Context.Mappings.IsKnownInterface(expression.Object.Type)) { // Query is testing equality on a property that maps to an entity type if (expression.Arguments[0].NodeType == ExpressionType.Constant) { _filterExpressionBuilder.Append("sameterm("); VisitExpression(expression.Object); _filterExpressionBuilder.Append(","); VisitExpression(expression.Arguments[0]); _filterExpressionBuilder.Append(")"); return(expression); } } if (expression.Object.NodeType == ExpressionType.MemberAccess) { var ma = expression.Object as MemberExpression; if (ma.Member is PropertyInfo) { var targetProperty = ma.Member as PropertyInfo; var propertyHint = QueryBuilder.Context.GetPropertyHint(targetProperty); if (propertyHint != null && propertyHint.MappingType == PropertyMappingType.Id) { if (expression.Arguments[0].NodeType == ExpressionType.Constant) { var constant = expression.Arguments[0] as ConstantExpression; _filterExpressionBuilder.Append("sameterm("); VisitExpression(expression.Object); _filterExpressionBuilder.Append(","); _filterExpressionBuilder.AppendFormat( "<{0}>", QueryBuilder.Context.MapIdToUri(targetProperty, constant.Value.ToString())); _filterExpressionBuilder.Append(")"); return(expression); } throw new NotSupportedException("Entity ID properties can only be compared to constant values"); } // Otherwise fall through to default handling } } _filterExpressionBuilder.Append('('); VisitExpression(expression.Object); _filterExpressionBuilder.Append("="); VisitExpression(expression.Arguments[0]); _filterExpressionBuilder.Append(')'); return(expression); } if (expression.Object != null && expression.Object.Type == typeof(String)) { if (expression.Method.Name.Equals("StartsWith")) { if (expression.Arguments[0].NodeType == ExpressionType.Constant) { var constantExpression = expression.Arguments[0] as ConstantExpression; if (expression.Arguments.Count == 1) { WriteFunction("STRSTARTS", expression.Object, expression.Arguments[0]); } else { var flags = SparqlGeneratorWhereExpressionTreeVisitor.GetStringComparisonFlags(expression.Arguments[1]); WriteRegexFilter(expression.Object, "^" + Regex.Escape(constantExpression.Value.ToString()), flags); return(expression); } return(expression); } } if (expression.Method.Name.Equals("EndsWith")) { if (expression.Arguments[0].NodeType == ExpressionType.Constant) { var constantExpression = expression.Arguments[0] as ConstantExpression; if (expression.Arguments.Count == 1) { WriteFunction("STRENDS", expression.Object, expression.Arguments[0]); } if (expression.Arguments.Count > 1 && expression.Arguments[1] is ConstantExpression) { string flags = SparqlGeneratorWhereExpressionTreeVisitor.GetStringComparisonFlags(expression.Arguments[1]); WriteRegexFilter(expression.Object, Regex.Escape(constantExpression.Value.ToString()) + "$", flags); } return(expression); } } if (expression.Method.Name.Equals("Contains")) { var seekValue = expression.Arguments[0] as ConstantExpression; if (seekValue != null) { if (expression.Arguments.Count == 1) { WriteFunction("CONTAINS", expression.Object, seekValue); } else if (expression.Arguments[1] is ConstantExpression) { var flags = SparqlGeneratorWhereExpressionTreeVisitor.GetStringComparisonFlags(expression.Arguments[1]); WriteRegexFilter(expression.Object, Regex.Escape(seekValue.Value.ToString()), flags); } return(expression); } } if (expression.Method.Name.Equals("Substring")) { Expression start; if (expression.Arguments[0] is ConstantExpression && expression.Arguments[0].Type == typeof(int)) { start = Expression.Constant(((int)(expression.Arguments[0] as ConstantExpression).Value) + 1); } else { start = Expression.Add(expression.Arguments[0], Expression.Constant(1)); } if (expression.Arguments.Count == 1) { WriteFunction("SUBSTR", expression.Object, start); return(expression); } if (expression.Arguments.Count == 2) { WriteFunction("SUBSTR", expression.Object, start, expression.Arguments[1]); return(expression); } } if (expression.Method.Name.Equals("ToUpper")) { WriteFunction("UCASE", expression.Object); return(expression); } if (expression.Method.Name.Equals("ToLower")) { WriteFunction("LCASE", expression.Object); return(expression); } if (expression.Method.Name.Equals("Replace")) { _regexEscaping = true; WriteFunction("REPLACE", expression.Object, expression.Arguments[0], expression.Arguments[1]); _regexEscaping = false; return(expression); } } if (expression.Object == null) { // Static method if (expression.Method.DeclaringType.Equals(typeof(Regex))) { if (expression.Method.Name.Equals("IsMatch")) { var sourceExpression = expression.Arguments[0]; var regexExpression = expression.Arguments[1] as ConstantExpression; var flagsExpression = expression.Arguments.Count > 2 ? expression.Arguments[2] as ConstantExpression : null; if (regexExpression != null) { var regex = regexExpression.Value.ToString(); string flags = String.Empty; if (flagsExpression != null && flagsExpression.Type == typeof(RegexOptions)) { var regexOptions = (RegexOptions)flagsExpression.Value; if ((regexOptions & RegexOptions.IgnoreCase) == RegexOptions.IgnoreCase) { flags += "i"; } if ((regexOptions & RegexOptions.Multiline) == RegexOptions.Multiline) { flags += "m"; } if ((regexOptions & RegexOptions.Singleline) == RegexOptions.Singleline) { flags += "s"; } if ((regexOptions & RegexOptions.IgnorePatternWhitespace) == RegexOptions.IgnorePatternWhitespace) { flags += "x"; } } WriteRegexFilter(sourceExpression, regex, String.Empty.Equals(flags) ? null : flags); return(expression); } } } if (typeof(String).Equals(expression.Method.DeclaringType)) { if (expression.Method.Name.Equals("Concat")) { WriteFunction("CONCAT", expression.Arguments.ToArray()); return(expression); } } if (typeof(Math).Equals(expression.Method.DeclaringType)) { string fnName = null; switch (expression.Method.Name) { case "Round": fnName = "ROUND"; break; case "Floor": fnName = "FLOOR"; break; case "Ceiling": fnName = "CEIL"; break; } if (fnName != null) { WriteFunction(fnName, expression.Arguments[0]); return(expression); } } } return(base.VisitMethodCallExpression(expression)); }
public FilterWriter(SparqlGeneratorWhereExpressionTreeVisitor parentVisitor, SparqlQueryBuilder queryBuilder, StringBuilder filterExpressionBuilder) : base(queryBuilder) { _parent = parentVisitor; _filterExpressionBuilder = filterExpressionBuilder; }