using System.Linq.Expressions; using System.Reflection; using Dapper; namespace MicroORM; public static class ExpressionToSqlTranslator { public static string Translate( Expression> 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(Expression> exp) { var body = exp.Body is UnaryExpression u ? u.Operand : exp.Body; var member = (MemberExpression)body; return OrmMetadata.GetColumnName((PropertyInfo)member.Member); } }