Files
Umbraco-CMS/src/Umbraco.Core/Persistence/Querying/ModelToSqlExpressionHelper.cs
2016-10-27 18:03:13 +02:00

81 lines
3.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Querying
{
/// <summary>
/// An expression tree parser to create SQL statements and SQL parameters based on a given strongly typed expression based on Umbraco's business logic Models
/// </summary>
/// <remarks>
/// This object stores state, it cannot be re-used to parse an expression
/// </remarks>
internal class ModelToSqlExpressionHelper<T> : BaseExpressionHelper
{
private readonly BaseMapper _mapper;
public ModelToSqlExpressionHelper(ISqlSyntaxProvider sqlSyntax, BaseMapper mapper) : base(sqlSyntax)
{
_mapper = mapper;
}
public ModelToSqlExpressionHelper() : this(SqlSyntaxContext.SqlSyntaxProvider, MappingResolver.Current.ResolveMapperByType(typeof(T)))
{
}
protected override string VisitMemberAccess(MemberExpression m)
{
if (m.Expression != null &&
m.Expression.NodeType == ExpressionType.Parameter
&& m.Expression.Type == typeof(T))
{
//don't execute if compiled
if (IsCompiled == false)
{
var field = _mapper.Map(m.Member.Name, true);
if (field.IsNullOrWhiteSpace())
throw new InvalidOperationException("The mapper returned an empty field for the member name: " + m.Member.Name);
return field;
}
//already compiled, return
return string.Empty;
}
if (m.Expression != null && m.Expression.NodeType == ExpressionType.Convert)
{
//don't execute if compiled
if (IsCompiled == false)
{
var field = _mapper.Map(m.Member.Name, true);
if (field.IsNullOrWhiteSpace())
throw new InvalidOperationException("The mapper returned an empty field for the member name: " + m.Member.Name);
return field;
}
//already compiled, return
return string.Empty;
}
var member = Expression.Convert(m, typeof(object));
var lambda = Expression.Lambda<Func<object>>(member);
var getter = lambda.Compile();
object o = getter();
SqlParameters.Add(o);
//don't execute if compiled
if (IsCompiled == false)
return string.Format("@{0}", SqlParameters.Count - 1);
//already compiled, return
return string.Empty;
}
}
}