3908 - Query build returns v8 valid statement - and examples of returned items

This commit is contained in:
Bjarke Berg
2019-01-17 13:33:44 +01:00
parent fe0d0ce1c7
commit 174db65714
6 changed files with 138 additions and 261 deletions

View File

@@ -1,97 +1,81 @@
namespace Umbraco.Web.Models.TemplateQuery
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using Umbraco.Core.Models.PublishedContent;
namespace Umbraco.Web.Models.TemplateQuery
{
public class QueryCondition
{
public PropertyModel Property { get; set; }
public OperatorTerm Term { get; set; }
public string ConstraintValue { get; set; }
}
internal static class QueryConditionExtensions
{
private static Lazy<MethodInfo> StringContainsMethodInfo =>
new Lazy<MethodInfo>(() => typeof(string).GetMethod("Contains", new[] {typeof(string)}));
public static string BuildTokenizedCondition(this QueryCondition condition, int token)
public static Expression<Func<IPublishedContent, bool>> BuildCondition(this QueryCondition condition,
string parameterAlias, IEnumerable<IPublishedContent> contents, IEnumerable<PropertyModel> properties)
{
return condition.BuildConditionString(string.Empty, token);
}
public static string BuildCondition(this QueryCondition condition, string parameterAlias)
{
return condition.BuildConditionString(parameterAlias + ".");
}
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 {
//modify the format of the constraint value
switch (condition.Property.Type)
{
case "string":
constraintValue = string.Format("\"{0}\"", condition.ConstraintValue);
break;
case "datetime":
constraintValue = string.Format("DateTime.Parse(\"{0}\")", condition.ConstraintValue);
break;
default:
constraintValue = condition.ConstraintValue;
break;
}
object constraintValue;
switch (condition.Property.Type)
{
case "string":
constraintValue = condition.ConstraintValue;
break;
case "datetime":
constraintValue = DateTime.Parse(condition.ConstraintValue);
break;
default:
constraintValue = Convert.ChangeType(condition.ConstraintValue, typeof(int));
break;
}
var parameterExpression = Expression.Parameter(typeof(IPublishedContent), parameterAlias);
var propertyExpression = Expression.Property(parameterExpression, condition.Property.Alias);
var valueExpression = Expression.Constant(constraintValue);
Expression bodyExpression;
switch (condition.Term.Operator)
{
case Operator.Equals:
operand = " == ";
break;
case Operator.NotEquals:
operand = " != ";
bodyExpression = Expression.NotEqual(propertyExpression, valueExpression);
break;
case Operator.GreaterThan:
operand = " > ";
bodyExpression = Expression.GreaterThan(propertyExpression, valueExpression);
break;
case Operator.GreaterThanEqualTo:
operand = " >= ";
bodyExpression = Expression.GreaterThanOrEqual(propertyExpression, valueExpression);
break;
case Operator.LessThan:
operand = " < ";
bodyExpression = Expression.LessThan(propertyExpression, valueExpression);
break;
case Operator.LessThanEqualTo:
operand = " <= ";
bodyExpression = Expression.LessThanOrEqual(propertyExpression, valueExpression);
break;
case Operator.Contains:
value = string.Format("{0}{1}.Contains({2})", prefix, condition.Property.Alias, constraintValue);
bodyExpression = Expression.Call(propertyExpression, StringContainsMethodInfo.Value,
valueExpression);
break;
case Operator.NotContains:
value = string.Format("!{0}{1}.Contains({2})", prefix, condition.Property.Alias, constraintValue);
var tempExpression = Expression.Call(propertyExpression, StringContainsMethodInfo.Value,
valueExpression);
bodyExpression = Expression.Equal(tempExpression, Expression.Constant(false));
break;
default :
operand = " == ";
default:
case Operator.Equals:
bodyExpression = Expression.Equal(propertyExpression, valueExpression);
break;
}
var predicate =
Expression.Lambda<Func<IPublishedContent, bool>>(bodyExpression.Reduce(), parameterExpression);
if (string.IsNullOrEmpty(value) == false)
return value;
return string.Format("{0}{1}{2}{3}", prefix, condition.Property.Alias, operand, constraintValue);
return predicate;
}
}
}

View File

@@ -9,7 +9,7 @@ namespace Umbraco.Web.Models.TemplateQuery
public string QueryExpression { get; set; }
public IEnumerable<TemplateQueryResult> SampleResults { get; set; }
public int ResultCount { get; set; }
public double ExecutionTime { get; set; }
public long ExecutionTime { get; set; }
public int Take { get; set; }
}
}