internal static ObjectQueryState Top( ObjectQueryState query, string alias, string count, ObjectParameter[] parameters) { int length = count.Length; string commandText = EntitySqlQueryBuilder.GetCommandText(query); bool allowsLimitSubclause = ((EntitySqlQueryState)query).AllowsLimitSubclause; StringBuilder queryText = new StringBuilder(!allowsLimitSubclause ? length + ("SELECT VALUE TOP(\r\n".Length + "\r\n) ".Length + alias.Length + "\r\nFROM (\r\n".Length + commandText.Length + "\r\n) AS ".Length + alias.Length) : length + (commandText.Length + "\r\nLIMIT\r\n".Length)); if (allowsLimitSubclause) { queryText.Append(commandText); queryText.Append("\r\nLIMIT\r\n"); queryText.Append(count); } else { queryText.Append("SELECT VALUE TOP(\r\n"); queryText.Append(count); queryText.Append("\r\n) "); queryText.Append(alias); queryText.Append("\r\nFROM (\r\n"); queryText.Append(commandText); queryText.Append("\r\n) AS "); queryText.Append(alias); } return(EntitySqlQueryBuilder.NewBuilderQuery(query, query.ElementType, queryText, query.Span, (IEnumerable <ObjectParameter>)EntitySqlQueryBuilder.MergeParameters(query.ObjectContext, query.Parameters, parameters))); }
private static ObjectQueryState BuildSelectOrSelectValue( ObjectQueryState query, string alias, string projection, ObjectParameter[] parameters, string projectOp, Type elementType) { DebugCheck.NotEmpty(alias); DebugCheck.NotEmpty(projection); var queryText = GetCommandText(query); // Build the new query string - "<project op> <projection> FROM (<this query>) AS <alias>" var queryLength = projectOp.Length + projection.Length + _fromOp.Length + queryText.Length + _asOp.Length + alias.Length; var builder = new StringBuilder(queryLength); builder.Append(projectOp); builder.Append(projection); builder.Append(_fromOp); builder.Append(queryText); builder.Append(_asOp); builder.Append(alias); // Create a new EntitySqlQueryImplementation that uses the new query as its command text. // Span should not be carried over from a Select or SelectValue operation. return(NewBuilderQuery(query, elementType, builder, null, MergeParameters(query.ObjectContext, query.Parameters, parameters))); }
internal static ObjectQueryState OfType(ObjectQueryState query, EdmType newType, Type clrOfType) { Debug.Assert(newType != null, "OfType cannot be null"); Debug.Assert(Helper.IsEntityType(newType) || Helper.IsComplexType(newType), "OfType must be Entity or Complex type"); var queryText = GetCommandText(query); // Build the new query string - "OFTYPE((<query>), [<type namespace>].[<type name>])" var queryLength = _ofTypeProlog.Length + queryText.Length + _ofTypeInfix.Length + newType.NamespaceName.Length + (!string.IsNullOrEmpty(newType.NamespaceName) ? _ofTypeInfix2.Length : 0) + newType.Name.Length + _ofTypeEpilog.Length; var builder = new StringBuilder(queryLength); builder.Append(_ofTypeProlog); builder.Append(queryText); builder.Append(_ofTypeInfix); if (!string.IsNullOrEmpty(newType.NamespaceName)) { builder.Append(newType.NamespaceName); builder.Append(_ofTypeInfix2); } builder.Append(newType.Name); builder.Append(_ofTypeEpilog); // Create a new EntitySqlQueryImplementation that uses the new query as its command text. // Span is carried over, no adjustment is needed return(NewBuilderQuery(query, clrOfType, builder, query.Span, ObjectParameterCollection.DeepCopy(query.Parameters))); }
private static ObjectQueryState BuildOrderByOrWhere( ObjectQueryState query, string alias, string predicateOrKeys, ObjectParameter[] parameters, string op, string skipCount, bool allowsLimit) { string commandText = EntitySqlQueryBuilder.GetCommandText(query); int capacity = "SELECT VALUE ".Length + alias.Length + "\r\nFROM (\r\n".Length + commandText.Length + "\r\n) AS ".Length + alias.Length + op.Length + predicateOrKeys.Length; if (skipCount != null) { capacity += "\r\nSKIP\r\n".Length + skipCount.Length; } StringBuilder queryText = new StringBuilder(capacity); queryText.Append("SELECT VALUE "); queryText.Append(alias); queryText.Append("\r\nFROM (\r\n"); queryText.Append(commandText); queryText.Append("\r\n) AS "); queryText.Append(alias); queryText.Append(op); queryText.Append(predicateOrKeys); if (skipCount != null) { queryText.Append("\r\nSKIP\r\n"); queryText.Append(skipCount); } return(EntitySqlQueryBuilder.NewBuilderQuery(query, query.ElementType, queryText, allowsLimit, query.Span, (IEnumerable <ObjectParameter>)EntitySqlQueryBuilder.MergeParameters(query.ObjectContext, query.Parameters, parameters))); }
internal static ObjectQueryState Select( ObjectQueryState query, string alias, string projection, ObjectParameter[] parameters) { return(EntitySqlQueryBuilder.BuildSelectOrSelectValue(query, alias, projection, parameters, "SELECT ", typeof(DbDataRecord))); }
internal static ObjectQueryState OrderBy( ObjectQueryState query, string alias, string keys, ObjectParameter[] parameters) { return(EntitySqlQueryBuilder.BuildOrderByOrWhere(query, alias, keys, parameters, "\r\nORDER BY\r\n", (string)null, true)); }
internal static ObjectQueryState Where( ObjectQueryState query, string alias, string predicate, ObjectParameter[] parameters) { return(EntitySqlQueryBuilder.BuildOrderByOrWhere(query, alias, predicate, parameters, "\r\nWHERE\r\n", (string)null, false)); }
internal static ObjectQueryState Intersect( ObjectQueryState leftQuery, ObjectQueryState rightQuery) { Span newSpan = Span.CopyUnion(leftQuery.Span, rightQuery.Span); return(EntitySqlQueryBuilder.BuildSetOp(leftQuery, rightQuery, newSpan, "\r\n) INTERSECT (\r\n")); }
internal static ObjectQueryState UnionAll(ObjectQueryState leftQuery, ObjectQueryState rightQuery) { // Ensure the Spans of the query arguments are merged into the new query's Span. var newSpan = Span.CopyUnion(leftQuery.Span, rightQuery.Span); // Call the SetOp helper. return(BuildSetOp(leftQuery, rightQuery, newSpan, _unionAllOp)); }
internal static ObjectQueryState UnionAll( ObjectQueryState leftQuery, ObjectQueryState rightQuery) { Span newSpan = Span.CopyUnion(leftQuery.Span, rightQuery.Span); return(EntitySqlQueryBuilder.BuildSetOp(leftQuery, rightQuery, newSpan, "\r\n) UNION ALL (\r\n")); }
// <summary> // Sets the values the <see cref="PlanCachingEnabled" /> and <see cref="UserSpecifiedMergeOption" /> properties on // <paramref name="other" /> to match the values of the corresponding properties on this instance. // </summary> // <param name="other"> The query state to which this instances settings should be applied. </param> internal void ApplySettingsTo(ObjectQueryState other) { other.PlanCachingEnabled = PlanCachingEnabled; other.UserSpecifiedMergeOption = UserSpecifiedMergeOption; // _cachedPlan is intentionally not copied over - since the parameters of 'other' would have to be locked as // soon as its execution plan was set, and that may not be appropriate at the time ApplySettingsTo is called. }
internal static ObjectQueryState SelectValue( ObjectQueryState query, string alias, string projection, ObjectParameter[] parameters, Type projectedType) { return(EntitySqlQueryBuilder.BuildSelectOrSelectValue(query, alias, projection, parameters, "SELECT VALUE ", projectedType)); }
private static ObjectQueryState NewBuilderQuery( ObjectQueryState sourceQuery, Type elementType, StringBuilder queryText, Span newSpan, IEnumerable <ObjectParameter> enumerableParams) { return(EntitySqlQueryBuilder.NewBuilderQuery(sourceQuery, elementType, queryText, false, newSpan, enumerableParams)); }
internal static ObjectQueryState Distinct(ObjectQueryState query) { string commandText = EntitySqlQueryBuilder.GetCommandText(query); StringBuilder queryText = new StringBuilder("SET(\r\n".Length + commandText.Length + "\r\n)".Length); queryText.Append("SET(\r\n"); queryText.Append(commandText); queryText.Append("\r\n)"); return(EntitySqlQueryBuilder.NewBuilderQuery(query, query.ElementType, queryText, query.Span, (IEnumerable <ObjectParameter>)ObjectParameterCollection.DeepCopy(query.Parameters))); }
private static string GetCommandText(ObjectQueryState query) { string commandText = (string)null; if (!query.TryGetCommandText(out commandText)) { throw new NotSupportedException(Strings.ObjectQuery_QueryBuilder_NotSupportedLinqSource); } return(commandText); }
internal static ObjectQueryState Top(ObjectQueryState query, string alias, string count, ObjectParameter[] parameters) { var queryLength = count.Length; var queryText = GetCommandText(query); var limitAllowed = ((EntitySqlQueryState)query).AllowsLimitSubclause; if (limitAllowed) { // Build the new query string: // <this query> LIMIT <count> queryLength += (queryText.Length + _limitOp.Length // + count.Length is added above ); } else { // Build the new query string: // "SELECT VALUE TOP(<count>) <alias> FROM (<this query>) AS <alias>" queryLength += (_topOp.Length + // count.Length + is added above _topInfix.Length + alias.Length + _fromOp.Length + queryText.Length + _asOp.Length + alias.Length); } var builder = new StringBuilder(queryLength); if (limitAllowed) { builder.Append(queryText); builder.Append(_limitOp); builder.Append(count); } else { builder.Append(_topOp); builder.Append(count); builder.Append(_topInfix); builder.Append(alias); builder.Append(_fromOp); builder.Append(queryText); builder.Append(_asOp); builder.Append(alias); } // Create a new EntitySqlQueryImplementation that uses the new query as its command text. // Span is carried over, no adjustment is needed. return(NewBuilderQuery( query, query.ElementType, builder, query.Span, MergeParameters(query.ObjectContext, query.Parameters, parameters))); }
private static ObjectQueryState BuildOrderByOrWhere( ObjectQueryState query, string alias, string predicateOrKeys, ObjectParameter[] parameters, string op, string skipCount, bool allowsLimit) { DebugCheck.NotEmpty(alias); DebugCheck.NotEmpty(predicateOrKeys); Debug.Assert(null == skipCount || op == _orderByOp, "Skip clause used with WHERE operator?"); var queryText = GetCommandText(query); // Build the new query string: // Either: "SELECT VALUE <alias> FROM (<this query>) AS <alias> WHERE <predicate>" // (for Where) // Or: "SELECT VALUE <alias> FROM (<this query>) AS <alias> ORDER BY <keys> <optional: SKIP <skip>>" // Depending on the value of 'op' var queryLength = _selectValueOp.Length + alias.Length + _fromOp.Length + queryText.Length + _asOp.Length + alias.Length + op.Length + predicateOrKeys.Length; if (skipCount != null) { queryLength += (_skipOp.Length + skipCount.Length); } var builder = new StringBuilder(queryLength); builder.Append(_selectValueOp); builder.Append(alias); builder.Append(_fromOp); builder.Append(queryText); builder.Append(_asOp); builder.Append(alias); builder.Append(op); builder.Append(predicateOrKeys); if (skipCount != null) { builder.Append(_skipOp); builder.Append(skipCount); } // Create a new EntitySqlQueryImplementation that uses the new query as its command text. // Span is carried over, no adjustment is needed. return(NewBuilderQuery( query, query.ElementType, builder, allowsLimit, query.Span, MergeParameters(query.ObjectContext, query.Parameters, parameters))); }
internal static ObjectQueryState Distinct(ObjectQueryState query) { // Build the new query string - "SET(<this query>)" var queryText = GetCommandText(query); var builder = new StringBuilder(_distinctProlog.Length + queryText.Length + _distinctEpilog.Length); builder.Append(_distinctProlog); builder.Append(queryText); builder.Append(_distinctEpilog); // Span is carried over, no adjustment is needed return(NewBuilderQuery(query, query.ElementType, builder, query.Span, ObjectParameterCollection.DeepCopy(query.Parameters))); }
private static ObjectQueryState BuildSelectOrSelectValue( ObjectQueryState query, string alias, string projection, ObjectParameter[] parameters, string projectOp, Type elementType) { string commandText = EntitySqlQueryBuilder.GetCommandText(query); StringBuilder queryText = new StringBuilder(projectOp.Length + projection.Length + "\r\nFROM (\r\n".Length + commandText.Length + "\r\n) AS ".Length + alias.Length); queryText.Append(projectOp); queryText.Append(projection); queryText.Append("\r\nFROM (\r\n"); queryText.Append(commandText); queryText.Append("\r\n) AS "); queryText.Append(alias); return(EntitySqlQueryBuilder.NewBuilderQuery(query, elementType, queryText, (Span)null, (IEnumerable <ObjectParameter>)EntitySqlQueryBuilder.MergeParameters(query.ObjectContext, query.Parameters, parameters))); }
internal static ObjectQueryState GroupBy( ObjectQueryState query, string alias, string keys, string projection, ObjectParameter[] parameters) { string commandText = EntitySqlQueryBuilder.GetCommandText(query); StringBuilder queryText = new StringBuilder("SELECT ".Length + projection.Length + "\r\nFROM (\r\n".Length + commandText.Length + "\r\n) AS ".Length + alias.Length + "\r\nGROUP BY\r\n".Length + keys.Length); queryText.Append("SELECT "); queryText.Append(projection); queryText.Append("\r\nFROM (\r\n"); queryText.Append(commandText); queryText.Append("\r\n) AS "); queryText.Append(alias); queryText.Append("\r\nGROUP BY\r\n"); queryText.Append(keys); return(EntitySqlQueryBuilder.NewBuilderQuery(query, typeof(DbDataRecord), queryText, (Span)null, (IEnumerable <ObjectParameter>)EntitySqlQueryBuilder.MergeParameters(query.ObjectContext, query.Parameters, parameters))); }
internal static ObjectQueryState OfType( ObjectQueryState query, EdmType newType, Type clrOfType) { string commandText = EntitySqlQueryBuilder.GetCommandText(query); StringBuilder queryText = new StringBuilder("OFTYPE(\r\n(\r\n".Length + commandText.Length + "\r\n),\r\n[".Length + newType.NamespaceName.Length + (!string.IsNullOrEmpty(newType.NamespaceName) ? "].[".Length : 0) + newType.Name.Length + "]\r\n)".Length); queryText.Append("OFTYPE(\r\n(\r\n"); queryText.Append(commandText); queryText.Append("\r\n),\r\n["); if (!string.IsNullOrEmpty(newType.NamespaceName)) { queryText.Append(newType.NamespaceName); queryText.Append("].["); } queryText.Append(newType.Name); queryText.Append("]\r\n)"); return(EntitySqlQueryBuilder.NewBuilderQuery(query, clrOfType, queryText, query.Span, (IEnumerable <ObjectParameter>)ObjectParameterCollection.DeepCopy(query.Parameters))); }
private static ObjectQueryState BuildSetOp( ObjectQueryState leftQuery, ObjectQueryState rightQuery, Span newSpan, string setOp) { string commandText1 = EntitySqlQueryBuilder.GetCommandText(leftQuery); string commandText2 = EntitySqlQueryBuilder.GetCommandText(rightQuery); if (!object.ReferenceEquals((object)leftQuery.ObjectContext, (object)rightQuery.ObjectContext)) { throw new ArgumentException(Strings.ObjectQuery_QueryBuilder_InvalidQueryArgument, "query"); } StringBuilder queryText = new StringBuilder("(\r\n".Length + commandText1.Length + setOp.Length + commandText2.Length + "\r\n)".Length); queryText.Append("(\r\n"); queryText.Append(commandText1); queryText.Append(setOp); queryText.Append(commandText2); queryText.Append("\r\n)"); return(EntitySqlQueryBuilder.NewBuilderQuery(leftQuery, leftQuery.ElementType, queryText, newSpan, (IEnumerable <ObjectParameter>)EntitySqlQueryBuilder.MergeParameters(leftQuery.Parameters, rightQuery.Parameters))); }
private static ObjectQueryState NewBuilderQuery( ObjectQueryState sourceQuery, Type elementType, StringBuilder queryText, bool allowsLimit, Span newSpan, IEnumerable <ObjectParameter> enumerableParams) { var queryParams = enumerableParams as ObjectParameterCollection; if (queryParams == null && enumerableParams != null) { queryParams = new ObjectParameterCollection(sourceQuery.ObjectContext.Perspective); foreach (var objectParam in enumerableParams) { queryParams.Add(objectParam); } } var newState = new EntitySqlQueryState( elementType, queryText.ToString(), allowsLimit, sourceQuery.ObjectContext, queryParams, newSpan); sourceQuery.ApplySettingsTo(newState); return(newState); }
private static ObjectQueryState BuildSetOp(ObjectQueryState leftQuery, ObjectQueryState rightQuery, Span newSpan, string setOp) { // Assert that the arguments aren't null (should have been verified by ObjectQuery) DebugCheck.NotNull(leftQuery); DebugCheck.NotNull(rightQuery); Debug.Assert( leftQuery.ElementType.Equals(rightQuery.ElementType), "Incompatible element types in arguments to Except<T>/Intersect<T>/Union<T>/UnionAll<T>?"); // Retrieve the left and right arguments to the set operation - // this will throw if either input query is not an Entity-SQL query. var left = GetCommandText(leftQuery); var right = GetCommandText(rightQuery); // ObjectQuery arguments must be associated with the same ObjectContext instance as the implemented query if (!ReferenceEquals(leftQuery.ObjectContext, rightQuery.ObjectContext)) { throw new ArgumentException(Strings.ObjectQuery_QueryBuilder_InvalidQueryArgument, "query"); } // Create a string builder only large enough to contain the new query text var queryLength = _setOpProlog.Length + left.Length + setOp.Length + right.Length + _setOpEpilog.Length; var builder = new StringBuilder(queryLength); // Build the new query builder.Append(_setOpProlog); builder.Append(left); builder.Append(setOp); builder.Append(right); builder.Append(_setOpEpilog); // Create a new query implementation and apply the state of this implementation to it. // The Span of the query argument will be merged into the new query's Span by the caller, iff the Set Op is NOT Except. // See the Except, Intersect, Union and UnionAll methods in this class for examples. return(NewBuilderQuery( leftQuery, leftQuery.ElementType, builder, newSpan, MergeParameters(leftQuery.Parameters, rightQuery.Parameters))); }
internal static ObjectQueryState GroupBy( ObjectQueryState query, string alias, string keys, string projection, ObjectParameter[] parameters) { DebugCheck.NotEmpty(alias); DebugCheck.NotEmpty(keys); DebugCheck.NotEmpty(projection); var queryText = GetCommandText(query); // Build the new query string: // "SELECT <projection> FROM (<this query>) AS <alias> GROUP BY <keys>" var queryLength = _selectOp.Length + projection.Length + _fromOp.Length + queryText.Length + _asOp.Length + alias.Length + _groupByOp.Length + keys.Length; var builder = new StringBuilder(queryLength); builder.Append(_selectOp); builder.Append(projection); builder.Append(_fromOp); builder.Append(queryText); builder.Append(_asOp); builder.Append(alias); builder.Append(_groupByOp); builder.Append(keys); // Create a new EntitySqlQueryImplementation that uses the new query as its command text. // Span should not be carried over from a GroupBy operation. return(NewBuilderQuery( query, typeof(DbDataRecord), builder, null, MergeParameters(query.ObjectContext, query.Parameters, parameters))); }
internal static ObjectQueryState Where(ObjectQueryState query, string alias, string predicate, ObjectParameter[] parameters) { return(BuildOrderByOrWhere(query, alias, predicate, parameters, _whereOp, null, false)); }
internal static ObjectQueryState OrderBy(ObjectQueryState query, string alias, string keys, ObjectParameter[] parameters) { return(BuildOrderByOrWhere(query, alias, keys, parameters, _orderByOp, null, true)); }
internal static ObjectQueryState Skip(ObjectQueryState query, string alias, string keys, string count, ObjectParameter[] parameters) { DebugCheck.NotEmpty(count); return(BuildOrderByOrWhere(query, alias, keys, parameters, _orderByOp, count, true)); }
internal static ObjectQueryState Select(ObjectQueryState query, string alias, string projection, ObjectParameter[] parameters) { return(BuildSelectOrSelectValue(query, alias, projection, parameters, _selectOp, typeof(DbDataRecord))); }
internal static ObjectQueryState SelectValue( ObjectQueryState query, string alias, string projection, ObjectParameter[] parameters, Type projectedType) { return(BuildSelectOrSelectValue(query, alias, projection, parameters, _selectValueOp, projectedType)); }