lambda 표현 식 변환 sql

using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace MaiCore { /// /// /// public class LambdaToSqlHelper { /// /// NodeType /// private enum EnumNodeType { /// /// /// [Description(" ")] BinaryOperator = 1, /// /// /// [Description(" ")] UndryOperator = 2, /// /// /// [Description(" ")] Constant = 3, /// /// ( ) /// [Description(" ( )")] MemberAccess = 4, /// /// /// [Description(" ")] Call = 5, /// /// /// [Description(" ")] Unknown = -99, /// /// /// [Description(" ")] NotSupported = -98 } /// /// /// /// lambda /// private static EnumNodeType CheckExpressionType(Expression exp) { switch (exp.NodeType) { case ExpressionType.AndAlso: case ExpressionType.OrElse: case ExpressionType.Equal: case ExpressionType.GreaterThanOrEqual: case ExpressionType.LessThanOrEqual: case ExpressionType.GreaterThan: case ExpressionType.LessThan: case ExpressionType.NotEqual: return EnumNodeType.BinaryOperator; case ExpressionType.Constant: return EnumNodeType.Constant; case ExpressionType.MemberAccess: return EnumNodeType.MemberAccess; case ExpressionType.Call: return EnumNodeType.Call; case ExpressionType.Not: case ExpressionType.Convert: return EnumNodeType.UndryOperator; default: return EnumNodeType.Unknown; } } /// /// /// /// /// private static string ExpressionTypeCast(ExpressionType type) { switch (type) { case ExpressionType.And: case ExpressionType.AndAlso: return " and "; case ExpressionType.Equal: return " = "; case ExpressionType.GreaterThan: return " > "; case ExpressionType.GreaterThanOrEqual: return " >= "; case ExpressionType.LessThan: return " < "; case ExpressionType.LessThanOrEqual: return " <= "; case ExpressionType.NotEqual: return " <> "; case ExpressionType.Or: case ExpressionType.OrElse: return " or "; case ExpressionType.Add: case ExpressionType.AddChecked: return " + "; case ExpressionType.Subtract: case ExpressionType.SubtractChecked: return " - "; case ExpressionType.Divide: return " / "; case ExpressionType.Multiply: case ExpressionType.MultiplyChecked: return " * "; default: return null; } } private static string BinarExpressionProvider(Expression exp, List listSqlParaModel) { BinaryExpression be = exp as BinaryExpression; Expression left = be.Left; Expression right = be.Right; ExpressionType type = be.NodeType; string sb = "("; // sb += ExpressionRouter(left, listSqlParaModel); sb += ExpressionTypeCast(type); // string sbTmp = ExpressionRouter(right, listSqlParaModel); if (sbTmp == "null") { if (sb.EndsWith(" = ")) sb = sb.Substring(0, sb.Length - 2) + " is null"; else if (sb.EndsWith(" <> ")) sb = sb.Substring(0, sb.Length - 2) + " is not null"; } else sb += sbTmp; return sb += ")"; } private static string ConstantExpressionProvider(Expression exp, List listSqlParaModel) { ConstantExpression ce = exp as ConstantExpression; if (ce.Value == null) { return "null"; } else if (ce.Value is ValueType) { GetSqlParaModel(listSqlParaModel, GetValueType(ce.Value)); return "@para" + listSqlParaModel.Count; } else if (ce.Value is string || ce.Value is DateTime || ce.Value is char) { GetSqlParaModel(listSqlParaModel, GetValueType(ce.Value)); return "@para" + listSqlParaModel.Count; } return ""; } private static string LambdaExpressionProvider(Expression exp, List listSqlParaModel) { LambdaExpression le = exp as LambdaExpression; return ExpressionRouter(le.Body, listSqlParaModel); } private static string MemberExpressionProvider(Expression exp, List listSqlParaModel) { if (!exp.ToString().StartsWith("value")) { MemberExpression me = exp as MemberExpression; if (me.Member.Name == "Now") { GetSqlParaModel(listSqlParaModel, DateTime.Now); return "@para" + listSqlParaModel.Count; } return me.Member.Name; } else { var result = Expression.Lambda(exp).Compile().DynamicInvoke(); if (result == null) { return "null"; } else if (result is ValueType) { GetSqlParaModel(listSqlParaModel, GetValueType(result)); return "@para" + listSqlParaModel.Count; } else if (result is string || result is DateTime || result is char) { GetSqlParaModel(listSqlParaModel, GetValueType(result)); return "@para" + listSqlParaModel.Count; } else if (result is int[]) { var rl = result as int[]; StringBuilder sbTmp = new StringBuilder(); foreach (var r in rl) { GetSqlParaModel(listSqlParaModel, r.ToString().ToInt32()); sbTmp.Append("@para" + listSqlParaModel.Count + ","); } return sbTmp.ToString().Substring(0, sbTmp.ToString().Length - 1); } else if (result is string[]) { var rl = result as string[]; StringBuilder sbTmp = new StringBuilder(); foreach (var r in rl) { GetSqlParaModel(listSqlParaModel, r.ToString()); sbTmp.Append("@para" + listSqlParaModel.Count + ","); } return sbTmp.ToString().Substring(0, sbTmp.ToString().Length - 1); } } return ""; } private static string MethodCallExpressionProvider(Expression exp, List listSqlParaModel) { MethodCallExpression mce = exp as MethodCallExpression; if (mce.Method.Name == "Contains") { if (mce.Object == null) { return string.Format("{0} in ({1})", ExpressionRouter(mce.Arguments[1], listSqlParaModel), ExpressionRouter(mce.Arguments[0], listSqlParaModel)); } else { if (mce.Object.NodeType == ExpressionType.MemberAccess) { //w => w.name.Contains("1") var _name = ExpressionRouter(mce.Object, listSqlParaModel); var _value = ExpressionRouter(mce.Arguments[0], listSqlParaModel); var index = _value.RetainNumber().ToInt32() - 1; listSqlParaModel[index].value = "%{0}%".FormatWith(listSqlParaModel[index].value); return string.Format("{0} like {1}", _name, _value); } } } else if (mce.Method.Name == "OrderBy") { return string.Format("{0} asc", ExpressionRouter(mce.Arguments[1], listSqlParaModel)); } else if (mce.Method.Name == "OrderByDescending") { return string.Format("{0} desc", ExpressionRouter(mce.Arguments[1], listSqlParaModel)); } else if (mce.Method.Name == "ThenBy") { return string.Format("{0},{1} asc", MethodCallExpressionProvider(mce.Arguments[0], listSqlParaModel), ExpressionRouter(mce.Arguments[1], listSqlParaModel)); } else if (mce.Method.Name == "ThenByDescending") { return string.Format("{0},{1} desc", MethodCallExpressionProvider(mce.Arguments[0], listSqlParaModel), ExpressionRouter(mce.Arguments[1], listSqlParaModel)); } else if (mce.Method.Name == "Like") { return string.Format("({0} like {1})", ExpressionRouter(mce.Arguments[0], listSqlParaModel), ExpressionRouter(mce.Arguments[1], listSqlParaModel).Replace("'", "")); } else if (mce.Method.Name == "NotLike") { return string.Format("({0} not like '%{1}%')", ExpressionRouter(mce.Arguments[0], listSqlParaModel), ExpressionRouter(mce.Arguments[1], listSqlParaModel).Replace("'", "")); } else if (mce.Method.Name == "In") { return string.Format("{0} in ({1})", ExpressionRouter(mce.Arguments[0], listSqlParaModel), ExpressionRouter(mce.Arguments[1], listSqlParaModel)); } else if (mce.Method.Name == "NotIn") { return string.Format("{0} not in ({1})", ExpressionRouter(mce.Arguments[0], listSqlParaModel), ExpressionRouter(mce.Arguments[1], listSqlParaModel)); } return ""; } private static string NewArrayExpressionProvider(Expression exp, List listSqlParaModel) { NewArrayExpression ae = exp as NewArrayExpression; StringBuilder sbTmp = new StringBuilder(); foreach (Expression ex in ae.Expressions) { sbTmp.Append(ExpressionRouter(ex, listSqlParaModel)); sbTmp.Append(","); } return sbTmp.ToString(0, sbTmp.Length - 1); } private static string ParameterExpressionProvider(Expression exp, List listSqlParaModel) { ParameterExpression pe = exp as ParameterExpression; return pe.Type.Name; } private static string UnaryExpressionProvider(Expression exp, List listSqlParaModel) { UnaryExpression ue = exp as UnaryExpression; var result = ExpressionRouter(ue.Operand, listSqlParaModel); ExpressionType type = exp.NodeType; if (type == ExpressionType.Not) { if (result.Contains(" in ")) { result = result.Replace(" in ", " not in "); } if (result.Contains(" like ")) { result = result.Replace(" like ", " not like "); } } return result; } /// /// /// /// /// /// private static string ExpressionRouter(Expression exp, List listSqlParaModel) { var nodeType = exp.NodeType; if (exp is BinaryExpression) // { return BinarExpressionProvider(exp, listSqlParaModel); } else if (exp is ConstantExpression) // { return ConstantExpressionProvider(exp, listSqlParaModel); } else if (exp is LambdaExpression) // lambda 。 .NET { return LambdaExpressionProvider(exp, listSqlParaModel); } else if (exp is MemberExpression) // { return MemberExpressionProvider(exp, listSqlParaModel); } else if (exp is MethodCallExpression) // { return MethodCallExpressionProvider(exp, listSqlParaModel); } else if (exp is NewArrayExpression) // { return NewArrayExpressionProvider(exp, listSqlParaModel); } else if (exp is ParameterExpression) // { return ParameterExpressionProvider(exp, listSqlParaModel); } else if (exp is UnaryExpression) // { return UnaryExpressionProvider(exp, listSqlParaModel); } return null; } /// /// /// /// /// private static object GetValueType(object _value) { var _type = _value.GetType().Name; switch (_type) { case "Decimal ": return _value.ToDecimal(); case "Int32": return _value.ToInt32(); case "DateTime": return _value.ToDateTime(); case "String": return _value.ToString(); case "Char":return _value.ToChar(); case "Boolean":return _value.ToBoolean(); default: return _value; } } /// /// sql /// /// /// private static void GetSqlParaModel(List listSqlParaModel, object val) { SqlParaModel p = new SqlParaModel(); p.name = "para" + (listSqlParaModel.Count + 1); p.value = val; listSqlParaModel.Add(p); } /// /// lambda sql /// /// /// /// /// public static string GetWhereSql(Expressionbool>> where, List listSqlParaModel) where T : class { string result = string.Empty; if (where != null) { Expression exp = where.Body as Expression; result = ExpressionRouter(exp, listSqlParaModel); } if (result != string.Empty) { result = " where " + result; } return result; } /// /// lambda sql /// /// /// /// public static string GetOrderBySql(Expression, IOrderedQueryable>> orderBy) where T : class { string result = string.Empty; if (orderBy != null && orderBy.Body is MethodCallExpression) { MethodCallExpression exp = orderBy.Body as MethodCallExpression; List listSqlParaModel = new List(); result = MethodCallExpressionProvider(exp, listSqlParaModel); } if (result != string.Empty) { result = " order by " + result; } return result; } /// /// lambda sql /// /// /// /// public static string GetQueryField(Expressionobject>> fields) { StringBuilder sbSelectFields = new StringBuilder(); if (fields.Body is NewExpression) { NewExpression ne = fields.Body as NewExpression; for (var i = 0; i < ne.Members.Count; i++) { sbSelectFields.Append(ne.Members[i].Name + ","); } } else if (fields.Body is ParameterExpression) { sbSelectFields.Append("*"); } else { sbSelectFields.Append("*"); } if (sbSelectFields.Length > 1) { sbSelectFields = sbSelectFields.Remove(sbSelectFields.Length - 1, 1); } return sbSelectFields.ToString(); } } } ----------------------------------------------------------------------------------------------- demo: class Program { static void Main(string[] args) { //Expression> where = w => w.id == "123456"; Expressionbool>> where = w => w.id.Contains("1"); List listSqlParaModel = new List(); var sql = LambdaToSqlHelper.GetWhereSql(where, listSqlParaModel); } } class MyClass { public string id; public string name; public string desc; public decimal price; public int stock; public bool isShow; public DateTime createTime; }

 

:https://www.cnblogs.com/zzp0320/p/7154895.html

좋은 웹페이지 즐겨찾기