C# Expression 树转化为SQL与语句(四)–修正参数本身方法调用的bug


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace TestExp
{
public class ExpressionToSql
{
public string GetSql<T>(Expression<Func<T, T>> exp)
{
return DealExpression(exp.Body);
}
public string GetSql<T>(Expression<Func<T, bool>> exp)
{
return DealExpression(exp.Body);
}
private object Eval(MemberExpression member)
{
var cast = Expression.Convert(member, typeof(object));
object c = Expression.Lambda<Func<object>>(cast).Compile().Invoke();
return GetValueFormat(c);
}
private string DealExpression(Expression exp, bool need = false)
{
string name = exp.GetType().Name;
switch (name)
{
case "BinaryExpression":
case "LogicalBinaryExpression":
case "MethodBinaryExpression":
case "SimpleBinaryExpression":
{
BinaryExpression b_exp = exp as BinaryExpression;
if (exp.NodeType == ExpressionType.Add
|| exp.NodeType == ExpressionType.Subtract
//|| exp.NodeType == ExpressionType.Multiply
//|| exp.NodeType == ExpressionType.Divide
//|| exp.NodeType == ExpressionType.Modulo
)
{
return "(" + DealBinary(b_exp) + ")";
}
if (!need) return DealBinary(b_exp);
BinaryExpression b_left = b_exp.Left as BinaryExpression;
BinaryExpression b_right = b_exp.Right as BinaryExpression;
if (b_left != null && b_right != null)
{
return "(" + DealBinary(b_exp) + ")";
}
return DealBinary(b_exp);
}
case "MemberExpression":
case "PropertyExpression":
case "FieldExpression":
return DealMember(exp as MemberExpression);
case "ConstantExpression": return DealConstant(exp as ConstantExpression);
case "MemberInitExpression":
return DealMemberInit(exp as MemberInitExpression);
case "UnaryExpression": return DealUnary(exp as UnaryExpression);
case "MethodCallExpressionN":
{
return DealMethodsCall(exp as MethodCallExpression);
}
case "InstanceMethodCallExpression0":
{
//// The original expression
//Expression<Func<Person1, bool>> expr = (x) => x.Birthday.AddMinutes(1) > DateTime.UtcNow;
//// Decompose the original expr.
//ParameterExpression param = (ParameterExpression)expr.Parameters[0];
//BinaryExpression operation = (BinaryExpression)expr.Body;
//var leftExpr = operation.Left;
//if (leftExpr is MethodCallExpression)
//{
//    MethodCallExpression expression = (MethodCallExpression)leftExpr;
//    object result = Expression.Lambda(expression, param).Compile().
//        DynamicInvoke(new Person1() { Birthday = DateTime.Parse("06-03-2020") });
//}
//return "";
var cast = Expression.Convert(exp, typeof(object));
object c = Expression.Lambda<Func<object>>(cast).Compile().Invoke();
return GetValueFormat(c);
}
default:
Console.WriteLine("error:" + name);
return "";
}
}
private string DealFieldAccess(FieldAccessException f_exp)
{
var c = f_exp;
return "";
}
private string DealMethodsCall(MethodCallExpression m_exp)
{
var k = m_exp;
var g = k.Arguments[0];
/// 控制函数所在类名。
if (k.Method.DeclaringType != typeof(SQLMethods))
{
throw new Exception("无法识别函数");
}
switch (k.Method.Name)
{
case "DB_Length":
{
var exp = k.Arguments[0];
return "LEN(" + DealExpression(exp) + ")";
}
case "DB_In":
case "DB_NotIn":
{
var exp1 = k.Arguments[0];
var exp2 = k.Arguments[1];
string methods = string.Empty;
if (k.Method.Name == "In")
{
methods = " IN ";
}
else
{
methods = " NOT IN ";
}
return DealExpression(exp1) + methods + DealExpression(exp2);
}
case "DB_Like":
case "DB_NotLike":
{
var exp1 = k.Arguments[0];
var exp2 = k.Arguments[1];
string methods = string.Empty;
if (k.Method.Name == "DB_Like")
{
methods = " LIKE ";
}
else
{
methods = " NOT LIKE ";
}
return DealExpression(exp1) + methods + DealExpression(exp2);
}
}
///   未知的函数
throw new Exception("意外的函数");
}
private string DealUnary(UnaryExpression u_exp)
{
var m = u_exp;
return DealExpression(u_exp.Operand);
}
private string DealMemberInit(MemberInitExpression mi_exp)
{
var i = 0;
string exp_str = string.Empty;
foreach (var item in mi_exp.Bindings)
{
MemberAssignment c = item as MemberAssignment;
if (i == 0)
{
exp_str += c.Member.Name.ToUpper() + "=" + DealExpression(c.Expression);
}
else
{
exp_str += "," + c.Member.Name.ToUpper() + "=" + DealExpression(c.Expression);
}
i++;
}
return exp_str;
}
private string DealBinary(BinaryExpression exp)
{
return DealExpression(exp.Left) + NullValueDeal(exp.NodeType, DealExpression(exp.Right, true));// GetOperStr(exp.NodeType) + DealExpression(exp.Right, true);
}
private string GetOperStr(ExpressionType e_type)
{
switch (e_type)
{
case ExpressionType.OrElse: return " OR ";
case ExpressionType.Or: return "|";
case ExpressionType.AndAlso: return " AND ";
case ExpressionType.And: return "&";
case ExpressionType.GreaterThan: return ">";
case ExpressionType.GreaterThanOrEqual: return ">=";
case ExpressionType.LessThan: return "<";
case ExpressionType.LessThanOrEqual: return "<=";
case ExpressionType.NotEqual: return "<>";
case ExpressionType.Add: return "+";
case ExpressionType.Subtract: return "-";
case ExpressionType.Multiply: return "*";
case ExpressionType.Divide: return "/";
case ExpressionType.Modulo: return "%";
case ExpressionType.Equal: return "=";
}
return "";
}
private string DealField(MemberExpression exp)
{
return Eval(exp).ToString();
}
private string DealMember(MemberExpression exp)
{
if (exp.Expression != null)
{
if (exp.Expression.GetType().Name == "TypedParameterExpression")
{
return exp.Member.Name;
}
return Eval(exp).ToString();
}
Type type = exp.Member.ReflectedType;
PropertyInfo propertyInfo = type.GetProperty(exp.Member.Name, BindingFlags.Static | BindingFlags.Public);
object o;
if (propertyInfo != null)
{
o = propertyInfo.GetValue(null);
}
else
{
FieldInfo field = type.GetField(exp.Member.Name, BindingFlags.Static | BindingFlags.Public);
o = field.GetValue(null);
}
return GetValueFormat(o);
}
private string DealConstant(ConstantExpression exp)
{
var ccc = exp.Value.GetType();
if (exp.Value == null)
{
return "NULL";
}
return GetValueFormat(exp.Value);
}
private string NullValueDeal(ExpressionType NodeType, string value)
{
if (value.ToUpper() != "NULL")
{
return GetOperStr(NodeType) + value;
}
switch (NodeType)
{
case ExpressionType.NotEqual:
{
return " IS NOT NULL ";
}
case ExpressionType.Equal:
{
return " IS NULL ";
}
default: return GetOperStr(NodeType) + value;
}
}
private string GetValueFormat(object obj)
{
var type = obj.GetType();
if (type.Name == "List`1") //list集合
{
List<string> data = new List<string>();
var list = obj as IEnumerable;
string sql = string.Empty;
foreach (var item in list)
{
data.Add(GetValueFormat(item));
}
sql = "(" + string.Join(",", data) + ")";
return sql;
}
if (type == typeof(string))// 
{
return string.Format("'{0}'", obj.ToString());
}
if (type == typeof(DateTime))
{
DateTime dt = (DateTime)obj;
return string.Format("'{0}'", dt.ToString("yyyy-MM-dd HH:mm:ss fff"));
}
return obj.ToString();
}
}
public static class SQLMethods
{
public static bool DB_In<T>(this T t, List<T> list)  // in
{
return true;
}
public static Boolean DB_NotIn<T>(this T t, List<T> list) // not in
{
return true;
}
public static int DB_Length(this string t)  // len();
{
return 0;
}
public static bool DB_Like(this string t, string str) // like
{
return true;
}
public static bool DB_NotLike(this string t, string str) // not like 
{
return true;
}
}
}

  

 

main函数:

using System.Linq.Expressions;
using System.Reflection;
using TestExp;
class programe
{
public static void Main(string[] args)
{
var v = 500.ToString();
var con = new ExpressionToSql();
var sql = con.GetSql<Student>(x => x.name == v.ToString().ToString());
Console.WriteLine(sql);
Console.ReadLine();
}
public class Student
{
public int id { get; set; }
public string name { get; set; }
public int math { get; set; } //数学成绩
public DateTime createTime { get; set; }
}
}

  

原创文章,作者:kepupublish,如若转载,请注明出处:https://blog.ytso.com/244775.html

(0)
上一篇 2022年4月17日
下一篇 2022年4月17日

相关推荐

发表回复

登录后才能评论