69 lines
2.2 KiB
C#
69 lines
2.2 KiB
C#
using System.Linq.Expressions;
|
|
using System.Reflection;
|
|
using Dapper;
|
|
|
|
namespace MicroORM;
|
|
|
|
public static class ExpressionToSqlTranslator
|
|
{
|
|
public static string Translate<T>(
|
|
Expression<Func<T, bool>> expression,
|
|
DynamicParameters parameters)
|
|
{
|
|
return Visit(expression.Body, parameters);
|
|
}
|
|
|
|
private static string Visit(Expression exp, DynamicParameters parameters)
|
|
{
|
|
return exp switch
|
|
{
|
|
BinaryExpression b => VisitBinary(b, parameters),
|
|
MemberExpression m => GetColumnName(m),
|
|
ConstantExpression c => AddParameter(c, parameters),
|
|
UnaryExpression u => Visit(u.Operand, parameters),
|
|
_ => throw new NotSupportedException($"Expression no soportada: {exp.NodeType}")
|
|
};
|
|
}
|
|
|
|
private static string VisitBinary(BinaryExpression b, DynamicParameters parameters)
|
|
{
|
|
var left = Visit(b.Left, parameters);
|
|
var right = Visit(b.Right, parameters);
|
|
|
|
var op = b.NodeType switch
|
|
{
|
|
ExpressionType.Equal => "=",
|
|
ExpressionType.NotEqual => "<>",
|
|
ExpressionType.GreaterThan => ">",
|
|
ExpressionType.GreaterThanOrEqual => ">=",
|
|
ExpressionType.LessThan => "<",
|
|
ExpressionType.LessThanOrEqual => "<=",
|
|
ExpressionType.AndAlso => "AND",
|
|
ExpressionType.OrElse => "OR",
|
|
_ => throw new NotSupportedException($"Operador no soportado: {b.NodeType}")
|
|
};
|
|
|
|
return $"({left} {op} {right})";
|
|
}
|
|
|
|
private static string GetColumnName(MemberExpression m)
|
|
{
|
|
var prop = (PropertyInfo)m.Member;
|
|
return OrmMetadata.GetColumnName(prop);
|
|
}
|
|
|
|
private static string AddParameter(ConstantExpression c, DynamicParameters parameters)
|
|
{
|
|
var name = $"@p{parameters.ParameterNames.Count()}";
|
|
parameters.Add(name, c.Value);
|
|
return name;
|
|
}
|
|
|
|
public static string GetOrderByColumn<T>(Expression<Func<T, object>> exp)
|
|
{
|
|
var body = exp.Body is UnaryExpression u ? u.Operand : exp.Body;
|
|
var member = (MemberExpression)body;
|
|
return OrmMetadata.GetColumnName((PropertyInfo)member.Member);
|
|
}
|
|
}
|