diff --git a/src/Umbraco.Web/Editors/TemplateQueryController.cs b/src/Umbraco.Web/Editors/TemplateQueryController.cs index a68c3bb9e0..2720847890 100644 --- a/src/Umbraco.Web/Editors/TemplateQueryController.cs +++ b/src/Umbraco.Web/Editors/TemplateQueryController.cs @@ -64,7 +64,8 @@ namespace Umbraco.Web.Editors var queryResult = new QueryResultModel(); var sb = new StringBuilder(); - + var indention = Environment.NewLine + "\t\t\t\t\t\t"; + sb.Append("Model.Content.Site()"); var timer = new Stopwatch(); @@ -129,7 +130,9 @@ namespace Umbraco.Web.Editors sb.Append(".Children"); } + //setup 2 clauses, 1 for returning, 1 for testing var clause = string.Empty; + var tokenizedClause = string.Empty; // WHERE var token = 0; @@ -141,12 +144,13 @@ namespace Umbraco.Web.Editors foreach (var condition in model.Filters) { if(string.IsNullOrEmpty( condition.ConstraintValue)) continue; - - - - var operation = condition.BuildCondition(token); + + //x is passed in as the parameter alias for the linq where statement clause + var operation = condition.BuildCondition("x"); + var tokenizedOperation = condition.BuildTokenizedCondition(token); clause = string.IsNullOrEmpty(clause) ? operation : string.Concat(new[] { clause, " && ", operation }); + tokenizedClause = string.IsNullOrEmpty(tokenizedClause) ? tokenizedOperation : string.Concat(new[] { tokenizedClause, " && ", tokenizedOperation }); token++; } @@ -156,19 +160,21 @@ namespace Umbraco.Web.Editors timer.Start(); - //clause = "Visible && " + clause; - - contents = contents.AsQueryable().Where(clause, model.Filters.Select(this.GetConstraintValue).ToArray()); - // contents = contents.Where(clause, values.ToArray()); + //trial-run the tokenized clause to time the execution + //for review - this uses a tonized query rather then the normal linq query. + contents = contents.AsQueryable().Where(tokenizedClause, model.Filters.Select(this.GetConstraintValue).ToArray()); contents = contents.Where(x => x.IsVisible()); timer.Stop(); - clause = string.Format("\"Visible && {0}\",{1}", clause, - string.Join(",", model.Filters.Select(x => x.Property.Type == "string" ? - string.Format("\"{0}\"", x.ConstraintValue) : x.ConstraintValue).ToArray())); + + //the query to output to the editor + sb.Append(indention); + sb.Append(".Where(x => x.IsVisible())"); + + sb.Append(indention); + sb.AppendFormat(".Where(x => {0})", clause); - sb.AppendFormat(".Where({0})", clause); } else { @@ -178,7 +184,8 @@ namespace Umbraco.Web.Editors timer.Stop(); - sb.Append(".Where(\"Visible\")"); + sb.Append(indention); + sb.Append(".Where(x => x.IsVisible())"); } @@ -192,6 +199,7 @@ namespace Umbraco.Web.Editors var direction = model.Sort.Direction == "ascending" ? string.Empty : " desc"; + sb.Append(indention); sb.AppendFormat(".OrderBy(\"{0}{1}\")", model.Sort.Property.Alias, direction); } @@ -203,6 +211,7 @@ namespace Umbraco.Web.Editors timer.Stop(); + sb.Append(indention); sb.AppendFormat(".Take({0})", model.Take); } } diff --git a/src/Umbraco.Web/Models/TemplateQuery/QueryCondition.cs b/src/Umbraco.Web/Models/TemplateQuery/QueryCondition.cs index 284518bf1e..a1047b8f19 100644 --- a/src/Umbraco.Web/Models/TemplateQuery/QueryCondition.cs +++ b/src/Umbraco.Web/Models/TemplateQuery/QueryCondition.cs @@ -11,16 +11,29 @@ internal static class QueryConditionExtensions { - private static string MakeBinaryOperation(this QueryCondition condition, string operand, int token) + + public static string BuildTokenizedCondition(this QueryCondition condition, int token) { - return string.Format("{0}{1}@{2}", condition.Property.Name, operand, token); + return condition.BuildConditionString(string.Empty, token); } + public static string BuildCondition(this QueryCondition condition, string parameterAlias) + { + return condition.BuildConditionString(parameterAlias + "."); + } - public static string BuildCondition(this QueryCondition condition, int token) + private static string BuildConditionString(this QueryCondition condition, string prefix, int token = -1) { var operand = string.Empty; var value = string.Empty; + var constraintValue = string.Empty; + + //if a token is used, use a token placeholder, otherwise, use the actual value + if(token >= 0){ + constraintValue = string.Format("@{0}", token); + }else { + constraintValue = condition.Property.Type == "string" ? string.Format("\"{0}\"", condition.ConstraintValue) : condition.ConstraintValue; + } switch (condition.Term.Operathor) { @@ -43,17 +56,20 @@ operand = " <= "; break; case Operathor.Contains: - value = string.Format("{0}.Contains(@{1})", condition.Property.Name, token); + value = string.Format("{0}{1}.Contains({2})", prefix, condition.Property.Name, constraintValue); break; case Operathor.NotContains: - value = string.Format("!{0}.Contains(@{1})", condition.Property.Name, token); + value = string.Format("!{0}{1}.Contains({2})", prefix, condition.Property.Name, constraintValue); break; default : operand = " == "; break; } - return string.IsNullOrEmpty(value) ? condition.MakeBinaryOperation(operand, token) : value; + if (string.IsNullOrEmpty(value) == false) + return value; + + return string.Format("{0}{1}{2}{3}", prefix, condition.Property.Name, operand, constraintValue); } }