public class SqlExpressionTree
{
public string GetQuerySql<T>(Expression<Func<T, bool>> condi)
{
string condition = "select * from "+typeof(T).Name+" "+ typeof(T).Name + " where ";
BinaryExpression body = (BinaryExpression)condi.Body;
condition+= GetSqlByExpression(body);
return condition;
}
/// <summary>
/// 通过Lambda解析为Sql
/// </summary>
/// <param name="func"></param>
/// <returns></returns>
public static string GetSqlByExpression(Expression func)
{
var funcType = CheckExpressionType(func);
switch (funcType)
{
case EnumNodeType.BinaryOperator:
return VisitBinaryExpression(func as BinaryExpression);
case EnumNodeType.Constant:
return VisitConstantExpression(func as ConstantExpression);
case EnumNodeType.Call:
return VisitMethodCallExpression(func as MethodCallExpression);
case EnumNodeType.UndryOperator:
return VisitUnaryExpression(func as UnaryExpression);
case EnumNodeType.MemberAccess:
return VisitMemberAccessExpression(func as MemberExpression);
default:
throw new NotSupportedException("不支持的操作在表达式处理中:");
}
}
public string CheckExpression(Expression exp)
{
string leftClude = "", rightClude = "";
if (exp.ToString().IndexOf("((") == )
{
leftClude = "("; rightClude = ")";
}
if (exp.NodeType == ExpressionType.MemberAccess || exp.NodeType == ExpressionType.Constant)
{
return exp.ToString();
}
if (exp as MethodCallExpression == null && exp as BinaryExpression == null)
throw new ArgumentException("不支持表达式的类型", "exp");
if (exp as MethodCallExpression != null)
{
MethodCallExpression cexp = exp as MethodCallExpression;
return "";
}
else
{
switch (exp.NodeType)
{
case ExpressionType.Equal:
return leftClude + CheckExpression(((BinaryExpression)exp).Left) + " = " + CheckExpression(((BinaryExpression)exp).Right) + rightClude;
case ExpressionType.Or:
return leftClude + CheckExpression(((BinaryExpression)exp).Left) + " or " + CheckExpression(((BinaryExpression)exp).Right) + rightClude;
case ExpressionType.OrElse:
return leftClude + CheckExpression(((BinaryExpression)exp).Left) + " or " + CheckExpression(((BinaryExpression)exp).Right) + rightClude;
case ExpressionType.AndAlso:
return leftClude + CheckExpression(((BinaryExpression)exp).Left) + " and " + CheckExpression(((BinaryExpression)exp).Right) + rightClude;
default:
return "";
}
}
}
/// <summary>
/// 判断表达式类型
/// </summary>
/// <param name="func">lambda表达式</param>
/// <returns></returns>
private static EnumNodeType CheckExpressionType(Expression func)
{
switch (func.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 ExpressionTypeToString(ExpressionType type)
{
switch (type)
{
case ExpressionType.Equal:
return " = ";
case ExpressionType.Or:
return " or ";
case ExpressionType.OrElse:
return " or ";
case ExpressionType.AndAlso:
return " and ";
default:
return "";
}
}
/// <summary>
/// 判断一元表达式
/// </summary>
/// <param name="func"></param>
/// <returns></returns>
private static string VisitUnaryExpression(UnaryExpression func)
{
var result = ExpressionTypeToString(func.NodeType);
var funcType = CheckExpressionType(func.Operand);
switch (funcType)
{
case EnumNodeType.BinaryOperator:
return result + VisitBinaryExpression(func.Operand as BinaryExpression);
case EnumNodeType.Constant:
return result + VisitConstantExpression(func.Operand as ConstantExpression);
case EnumNodeType.Call:
return result + VisitMethodCallExpression(func.Operand as MethodCallExpression);
case EnumNodeType.UndryOperator:
return result + VisitUnaryExpression(func.Operand as UnaryExpression);
case EnumNodeType.MemberAccess:
return result + VisitMemberAccessExpression(func.Operand as MemberExpression);
default:
throw new NotSupportedException("不支持的操作在一元操作处理中:");
}
} /// <summary>
/// 判断常量表达式
/// </summary>
/// <param name="func"></param>
/// <returns></returns>
private static string VisitConstantExpression(ConstantExpression func)
{
if (func.Value.ToString() == "")
{
return "\'\' ";
}
else if (func.Value.ToString() == "True")
{
return "1 = 1 ";
}
else if (func.Value.ToString() == "False")
{
return "0 = 1 ";
}
else
{
return "'" + func.Value.ToString() + "' "; }
} /// <summary>
/// 判断包含变量的表达式
/// </summary>
/// <param name="func"></param>
/// <returns></returns>
private static string VisitMemberAccessExpression(MemberExpression func)
{
try
{
var tablename = func.Expression.Type.Name;
return tablename + "." + func.Member.Name + " ";
}
catch
{
object value;
switch (func.Type.Name)
{
case "Int32":
{
var getter = Expression.Lambda<Func<int>>(func).Compile();
value = getter();
}
break;
case "String":
{
var getter = Expression.Lambda<Func<string>>(func).Compile();
value = "'" + getter() + "'";
}
break;
case "DateTime":
{
var getter = Expression.Lambda<Func<DateTime>>(func).Compile();
value = "'" + getter() + "'";
}
break;
default:
{
var getter = Expression.Lambda<Func<object>>(func).Compile();
value = getter();
}
break;
}
return value.ToString();
}
}
/// <summary>
/// 判断包含函数的表达式
/// </summary>
/// <param name="func"></param>
/// <returns></returns>
private static String VisitMethodCallExpression(MethodCallExpression func)
{
if (func.Method.Name.Contains("Contains"))
{
if (func.Object.Type.Name.ToLower() == "string")
{
//获得调用者的内容元素
var field = VisitMemberAccessExpression(func.Object as MemberExpression);
//获得字段
var caller = func.Arguments[];
var param = Expression.Lambda<Func<object>>(caller).Compile();
return field + " like '%" + param() + "%'";
}
else
{
//获得调用者的内容元素
var getter = Expression.Lambda<Func<object>>(func.Object).Compile();
var data = getter() as IEnumerable;
//获得字段
var caller = func.Arguments[];
while (caller.NodeType == ExpressionType.Call)
{
caller = (caller as MethodCallExpression).Object;
}
var field = VisitMemberAccessExpression(caller as MemberExpression);
var list = (from object i in data select "'" + i + "'").ToList();
return field + " IN (" + string.Join(",", list.Cast<string>().ToArray()) + ") ";
}
}
else
{
throw new NotSupportedException("不支持的函数操作:" + func.Method.Name);
}
}
/// <summary>
/// 判断包含二元运算符的表达式
/// </summary>
/// <remarks>注意,这个函数使用了递归,修改时注意不要修改了代码顺序和逻辑</remarks>
/// <param name="func"></param>
private static string VisitBinaryExpression(BinaryExpression func)
{
var result = "(";
var leftType = CheckExpressionType(func.Left);
switch (leftType)
{
case EnumNodeType.BinaryOperator:
result += VisitBinaryExpression(func.Left as BinaryExpression); break;
case EnumNodeType.Constant:
result += VisitConstantExpression(func.Left as ConstantExpression); break;
case EnumNodeType.MemberAccess:
result += VisitMemberAccessExpression(func.Left as MemberExpression); break;
case EnumNodeType.UndryOperator:
result += VisitUnaryExpression(func.Left as UnaryExpression); break;
case EnumNodeType.Call:
result += VisitMethodCallExpression(func.Left as MethodCallExpression); break;
default:
throw new NotSupportedException("不支持的操作在二元操作处理中:");
} result += ExpressionTypeToString(func.NodeType) + " "; var rightType = CheckExpressionType(func.Right);
switch (rightType)
{
case EnumNodeType.BinaryOperator:
result += VisitBinaryExpression(func.Right as BinaryExpression); break;
case EnumNodeType.Constant:
result += VisitConstantExpression(func.Right as ConstantExpression); break;
case EnumNodeType.MemberAccess:
result += VisitMemberAccessExpression(func.Right as MemberExpression); break;
case EnumNodeType.UndryOperator:
result += VisitUnaryExpression(func.Right as UnaryExpression); break;
case EnumNodeType.Call:
result += VisitMethodCallExpression(func.Right as MethodCallExpression); break;
default:
throw new NotSupportedException("不支持的操作在二元操作处理中:");
} result += ") ";
return result;
}
} public enum EnumNodeType
{
[Description("二元运算符")]
BinaryOperator = ,
[Description("一元运算符")]
UndryOperator = ,
[Description("常量表达式")]
Constant = ,
[Description("成员(变量)")]
MemberAccess = ,
[Description("函数")]
Call = ,
[Description("未知")]
Unknown = -,
[Description("不支持")]
NotSupported = -
}

Lambda转sql部分代码保存的更多相关文章

  1. 防SQL注入代码(ASP版)

    <% Dim Fy_Url,Fy_a,Fy_x,Fy_Cs(),Fy_Cl,Fy_Ts,Fy_Zx '---定义部份 头------ Fy_Cl = 1 '处理方式:1=提示信息,2=转向页面, ...

  2. Html代码保存为Pdf文件

    前段时间Insus.NET有实现了<上传Text文档并转换为PDF>http://www.cnblogs.com/insus/p/4313092.html 和<截取视图某一段另存为部 ...

  3. 大学站防SQL注入代码(ASP版)

    方法1: Replace过滤字符 解决方法:查找login.asp下的<from找到下边的类似username=request.Form(”name”) pass=request.Form(”p ...

  4. C#与数据库访问技术总结(六)之Command对象创建SQl语句代码示例

    Command对象创建SQl语句代码示例 说明:前面介绍了 Command 对象的方法和一些属性,回顾一下 Command对象主要用来执行SQL语句.利用Command对象,可以查询数据和修改数据. ...

  5. 判断字符串中是否有SQL攻击代码

    判断一个输入框中是否有SQL攻击代码 public const string SQLSTR2 = @"exec|cast|convert|set|insert|select|delete|u ...

  6. 定时任务redis锁+自定义lambda优化提取冗余代码

    功能介绍: 我系统中需要跑三个定时任务,由于是多节点部署,为了防止多个节点的定时任务重复执行.所以在定时任务执行时加个锁,抢到锁的节点才能执行定时任务,没有抢到锁的节点就不执行.从而避免了定时任务重复 ...

  7. 转:Excel导入SQL数据库完整代码

    Excel导入SQL数据库完整代码 protected void studentload_Click(object sender, EventArgs e) {//批量添加学生信息 SqlConnec ...

  8. SQL Server中Table字典数据的查询SQL示例代码

    SQL Server中Table字典数据的查询SQL示例代码 前言 在数据库系统原理与设计(第3版)教科书中这样写道: 数据库包含4类数据: 1.用户数据 2.元数据 3.索引 4.应用元数据 其中, ...

  9. java 连接mysql 和sql server2008代码

    这两天用java分别连接mysql和sql server2008代码.刚開始都是有错.如今找到了在 自己机器上成功连接的代码: 1. mysql Class.forName("com.mys ...

随机推荐

  1. Java钉钉开发_02_免登授权(身份验证)(附源码)

    源码已上传GitHub: https://github.com/shirayner/DingTalk_Demo 一.本节要点 1.免登授权的流程 (1)签名校验 (2)获取code,并传到后台 (3) ...

  2. Robberies hdu 2955 01背包

    Robberies Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  3. Python文件读写模式

    r 打开只读文件,该文件必须存在. r+ 打开可读写的文件,该文件必须存在.可读,可写,可追加. w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失.若文件不存在则建立该文件. w+ 打 ...

  4. 关于xamarin.forms 中 list 的loadmore

    前言 最近几天在研究上拉加载啊,下拉刷新啊什么的.然而坑爹的事情总是那么多.在xamarin.forms中,list自带的,并没有上拉加载的这个属性(难道当初他们封装方法时,就不会想到数据多了会咋整吗 ...

  5. C#泛型基础知识点总结

    1.0  什么是泛型 泛型是C#2.0和CLR(公共语言运行时)升级的一个新特性,泛型为.NET 框架引入了一个叫 type parameters(类型参数)的概念,type parameters 使 ...

  6. Ubuntu 14.04 安装 Sublime Text 3

    1. 实验环境 Ubuntu 14.04 + Sublime text 3 2. sublime text介绍 ublime Text 是一款流行的文本编辑器软件,有点类似于TextMate,跨平台, ...

  7. MVC中使用Echart后台加载数据 实现饼图、折线图、全国地图数据,单击双击事件等

    @{ Layout = null; } @if (false) { <script src="~/Js/jquery-easyui-1.5/jquery.min.js"> ...

  8. nginx + keepalived 实现高可靠web网站

    组网图: 配置信息: 左边nigx 服务器的 /usr/local/nginx/conf/nginx.conf #user  nobody; worker_processes  1; #error_l ...

  9. 【记录一次windows技术学习】使用笔记本DOS命令搭建WLAN热点

    [记录一次windows技术学习]使用笔记本DOS命令搭建WLAN热点 时间:2017-10-14 22:36:13 撰写者:AK末影人 [转发请注明出处] --------------------- ...

  10. checkbox插件

    1.全选或者全不选 首先判断全选或全不选checkbox是否被选中. 如果被选中,则为每个选项checkbox设置obj.checked='checked'; 如果未被选中,则为每个选项checkbo ...