private void Compile() { if (_query == null) { _query = SnExpression.BuildQuery(_queryable.Expression, typeof(T), _queryable.ContextPath, _queryable.ChildrenDefinition); } }
private void Compile() { if (_query == null) { var query = SnExpression.BuildQuery(_queryable.Expression, typeof(T), _queryable.ContextPath, _queryable.ChildrenDefinition); query.AddAndClause(SnExpression.GetPathPredicate(_queryable.ContextPath, _queryable.SubTree)); _query = query; } }
// ================================================================================================================================================== private ContentSet <Q> Clone <Q>(Expression expression) { if (typeof(Content) != typeof(Q)) { this.TypeFilter = typeof(Q); } if (typeof(Q) == typeof(Content) || typeof(Node).IsAssignableFrom(typeof(Q))) { return new ContentSet <Q>(expression, this.ChildrenDefinition.Clone(), this.ContextPath) { CountOnlyEnabled = this.CountOnlyEnabled, HeadersOnlyEnabled = this.HeadersOnlyEnabled, TypeFilter = this.TypeFilter } } ; if (expression is MethodCallExpression callExpr) { var lastMethodName = callExpr.Method.Name; throw SnExpression.CallingAsEnunerableExpectedError(lastMethodName); } throw SnExpression.CallingAsEnunerableExpectedError(expression); }
// ================================================================================================================================================== public SnQuery GetCompiledQuery() { var q = SnExpression.BuildQuery(this.Expression, typeof(T), this.ContextPath, this.ChildrenDefinition); return(q); }
public virtual TResult Execute <TResult>(Expression expression) { var count = 0; // in case there is a predefined list of nodes, we do not execute a query (but we still need to build it) if (!this.ExecuteQuery) { count = ChildrenDefinition.BaseCollection.Count(); } var query = SnExpression.BuildQuery(expression, typeof(T), this.ContextPath, this.ChildrenDefinition, out var elementSelection); if (TracingEnabled) { TraceLog.Append("Expression: ").AppendLine(expression.ToString()); TraceLog.Append("Query: ").AppendLine(query.ToString()); TraceLog.AppendLine("--------------"); } var result = this.ExecuteQuery ? query.Execute(SnQueryContext.CreateDefault()) : null; if (query.CountOnly) { if (this.ExecuteQuery) { count = result.TotalCount; } if (query.ExistenceOnly) { return((TResult)Convert.ChangeType(count > 0, typeof(TResult))); } return((TResult)Convert.ChangeType(count, typeof(TResult))); } if (this.ExecuteQuery) { count = result.TotalCount; } if (count == 0) { if (query.ThrowIfEmpty) { if (elementSelection == "elementat") { // ReSharper disable once NotResolvedInText throw new ArgumentOutOfRangeException("Index was out of range."); } else { throw new InvalidOperationException("Sequence contains no elements."); } } return(default(TResult)); } if (typeof(Node).IsAssignableFrom(typeof(TResult))) { if (ExecuteQuery) { return((TResult)Convert.ChangeType(Node.LoadNode(result.Hits.First()), typeof(TResult))); } return((TResult)Convert.ChangeType(ChildrenDefinition.BaseCollection.First(), typeof(TResult))); } switch (elementSelection) { case "first": return(ExecuteQuery ? (TResult)Convert.ChangeType(Content.Load(result.Hits.FirstOrDefault()), typeof(TResult)) : (TResult)Convert.ChangeType(Content.Create(ChildrenDefinition.BaseCollection.FirstOrDefault()), typeof(TResult))); case "last": return(ExecuteQuery ? (TResult)Convert.ChangeType(Content.Load(result.Hits.LastOrDefault()), typeof(TResult)) : (TResult)Convert.ChangeType(Content.Create(ChildrenDefinition.BaseCollection.LastOrDefault()), typeof(TResult))); case "single": return(ExecuteQuery ? (TResult)Convert.ChangeType(Content.Load(result.Hits.SingleOrDefault()), typeof(TResult)) : (TResult)Convert.ChangeType(Content.Create(ChildrenDefinition.BaseCollection.SingleOrDefault()), typeof(TResult))); case "elementat": var any = ExecuteQuery ? result.Hits.Any() : ChildrenDefinition.BaseCollection.Any(); if (!any) { if (query.ThrowIfEmpty) { // ReSharper disable once NotResolvedInText throw new ArgumentOutOfRangeException("Index was out of range."); } else { return(default(TResult)); } } return(ExecuteQuery ? (TResult)Convert.ChangeType(Content.Load(result.Hits.FirstOrDefault()), typeof(TResult)) : (TResult)Convert.ChangeType(Content.Create(ChildrenDefinition.BaseCollection.FirstOrDefault()), typeof(TResult))); default: throw new SnNotSupportedException(); } }
internal static SnQuery GetSnQuery(Expression expr, bool autoFiltersEnabled, bool lifespanEnabled, ChildrenDefinition childrenDef, string contextPath) { return(SnExpression.BuildQuery(expr, typeof(T), contextPath, childrenDef)); }
public virtual TResult Execute <TResult>(System.Linq.Expressions.Expression expression) { int count = 0; // in case there is a predefined list of nodes, we do not execute a query (but we still need to build it) if (!this.ExecuteQuery) { count = ChildrenDefinition.BaseCollection.Count(); } var query = SnExpression.BuildQuery(expression, typeof(T), this.ContextPath, this.ChildrenDefinition); if (TracingEnabled) { TraceLog.Append("Expression: ").AppendLine(expression.ToString()); TraceLog.Append("Query: ").AppendLine(query.ToString()); TraceLog.AppendLine("--------------"); } var result = this.ExecuteQuery ? query.Execute() : null; if (query.CountOnly) { if (this.ExecuteQuery) { count = query.TotalCount; } if (query.ExistenceOnly) { return((TResult)Convert.ChangeType(count > 0, typeof(TResult))); } else { return((TResult)Convert.ChangeType(count, typeof(TResult))); } } if (this.ExecuteQuery) { count = result.Count(); } if (count == 0) { if (query.ThrowIfEmpty) { throw new InvalidOperationException("Sequence contains no elements."); } return(default(TResult)); } if (count == 1) { if (typeof(Node).IsAssignableFrom(typeof(TResult))) { if (this.ExecuteQuery) { return((TResult)Convert.ChangeType(Node.LoadNode(result.First().NodeId), typeof(TResult))); } return((TResult)Convert.ChangeType(ChildrenDefinition.BaseCollection.First(), typeof(TResult))); } if (this.ExecuteQuery) { return((TResult)Convert.ChangeType(Content.Load(result.First().NodeId), typeof(TResult))); } return((TResult)Convert.ChangeType(Content.Create(ChildrenDefinition.BaseCollection.First()), typeof(TResult))); } throw new NotImplementedException("SnLinq: ContentSet.Execute<TResult>"); }
protected override Expression VisitMethodCall(MethodCallExpression node) { Trace(MethodBase.GetCurrentMethod(), node); Expression visited = null; try { visited = base.VisitMethodCall(node); } catch (SnNotSupportedException e) { throw SnExpression.CallingAsEnunerableExpectedError(node.Method.Name, e); } if (!(visited is MethodCallExpression methodCallExpr)) { throw new NotSupportedException("#VisitMethodCall if visited is not null"); } var methodName = methodCallExpr.Method.Name; switch (methodName) { case "OfType": // Do nothing. Type of expression has been changed so a TypeIs predicate will be created. case "Where": // do nothing break; case "Take": var topExpr = GetArgumentAsConstant(methodCallExpr, 1); this.Top = (int)topExpr.Value; break; case "Skip": var skipExpr = GetArgumentAsConstant(methodCallExpr, 1); this.Skip = (int)skipExpr.Value; break; case "LongCount": case "Count": if (methodCallExpr.Arguments.Count == 2) { if (_predicates.Count > 1) // There is Where in the main expression { CombineTwoPredicatesOnStack(); } } this.CountOnly = true; break; case "ThenBy": case "OrderBy": Sort.Add(CreateSortInfoFromExpr(node, false)); break; case "ThenByDescending": case "OrderByDescending": Sort.Add(CreateSortInfoFromExpr(node, true)); break; case "StartsWith": var startsWithExpr = GetArgumentAsConstant(methodCallExpr, 0); var startsWithArg = (string)startsWithExpr.Value; BuildWildcardPredicate(GetPropertyName(methodCallExpr.Object), WildcardPosition.AtEnd, startsWithArg); break; case "EndsWith": var endsWithExpr = GetArgumentAsConstant(methodCallExpr, 0); var endsWithArg = (string)endsWithExpr.Value; BuildWildcardPredicate(GetPropertyName(methodCallExpr.Object), WildcardPosition.AtStart, endsWithArg); break; case "Contains": var arg0 = methodCallExpr.Arguments[0]; if (arg0 is ConstantExpression constantExpr) { if (constantExpr.Type != typeof(string)) { throw new NotSupportedException( $"Calling Contains on an instance of type {constantExpr.Type} is not supported. Allowed types: string, IEnumerable<Node>."); } var containsArg = (string)constantExpr.Value; BuildWildcardPredicate(GetPropertyName(methodCallExpr.Object), WildcardPosition.AtStartAndEnd, containsArg); break; } if (arg0 is MemberExpression memberExpr) { if (memberExpr.Type != typeof(IEnumerable <Node>)) { throw NotSupportedException(node, "#2"); } if (!(methodCallExpr.Arguments[1] is ConstantExpression rightConstant)) { throw NotSupportedException(node, "#1"); } var nodeValue = (Node)rightConstant.Value; BuildTextPredicate(memberExpr.Member.Name, nodeValue); break; } throw NotSupportedException(node, "#3"); case "FirstOrDefault": case "First": ElementSelection = "first"; this.Top = 1; this.ThrowIfEmpty = methodName == "First"; if (methodCallExpr.Arguments.Count == 2) { if (_predicates.Count > 1) { CombineTwoPredicatesOnStack(); } } break; case "SingleOrDefault": case "Single": ElementSelection = "single"; this.ThrowIfEmpty = methodName == "Single"; if (methodCallExpr.Arguments.Count == 2) { if (_predicates.Count > 1) { CombineTwoPredicatesOnStack(); } } break; case "LastOrDefault": case "Last": ElementSelection = "last"; this.ThrowIfEmpty = methodName == "Last"; if (methodCallExpr.Arguments.Count == 2) { if (_predicates.Count > 1) { CombineTwoPredicatesOnStack(); } } break; case "ElementAtOrDefault": case "ElementAt": ElementSelection = "elementat"; this.ThrowIfEmpty = methodName == "ElementAt"; var constExpr = GetArgumentAsConstant(methodCallExpr, 1); var index = Convert.ToInt32(constExpr.Value); this.Skip = index; this.Top = 1; break; case "Any": ElementSelection = "first"; this.CountOnly = true; this.ExistenceOnly = true; this.Top = 1; if (methodCallExpr.Arguments.Count == 2) { if (_predicates.Count > 1) { CombineTwoPredicatesOnStack(); } } break; case "Type": var typeExpr = GetArgumentAsConstant(methodCallExpr, 0); BuildTextPredicate("Type", (string)typeExpr.Value); break; case "TypeIs": var typeIsExpr = GetArgumentAsConstant(methodCallExpr, 0); BuildTextPredicate("TypeIs", (string)(typeIsExpr).Value); break; case "get_Item": if (!(methodCallExpr.Object is ParameterExpression)) { throw new NotSupportedException("#get_Item"); } break; case "startswith": { var fieldName = GetPropertyName(methodCallExpr.Arguments[0]); var startswithExpr = GetArgumentAsConstant(methodCallExpr, 1); var arg = (string)startswithExpr.Value; BuildWildcardPredicate(fieldName, WildcardPosition.AtEnd, arg); break; } case "endswith": { var fieldName = GetPropertyName(methodCallExpr.Arguments[0]); var endswithExpr = GetArgumentAsConstant(methodCallExpr, 1); var arg = (string)endswithExpr.Value; BuildWildcardPredicate(fieldName, WildcardPosition.AtStart, arg); break; } case "substringof": { var fieldName = GetPropertyName(methodCallExpr.Arguments[1]); var substringofExpr = GetArgumentAsConstant(methodCallExpr, 0); var arg = (string)substringofExpr.Value; BuildWildcardPredicate(fieldName, WildcardPosition.AtStartAndEnd, arg); break; } case "isof": { var isofExpr = GetArgumentAsConstant(methodCallExpr, 1); BuildTextPredicate("TypeIs", (string)(isofExpr).Value); break; } case "InFolder": { var infolderexpr = GetArgumentAsConstant(methodCallExpr, 0); var folder = infolderexpr.Value; BuildTextPredicate("InFolder", GetPath(folder, "InFolder")); break; } case "InTree": { var intreeexpr = GetArgumentAsConstant(methodCallExpr, 0); var folder = intreeexpr.Value; BuildTextPredicate("InTree", GetPath(folder, "InTree")); break; } case "GetType": { if (methodCallExpr.Object is MemberExpression member && member.Member == typeof(Content).GetProperty("ContentHandler")) { _predicates.Push(new ContentHandlerGetTypePredicate()); }