3908 - Query build returns v8 valid statement - and examples of returned items
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user