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
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.