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. 渣渣学QT

    初学QT,自己的一些小总结,错误之处,望大神指点一二: 1,添加资源文件时想应用在界面的背景,但是发现用不了,后来才知道是没有"构建"?应该是要在构建之后才将所添加的资源文件真正的 ...

  2. ASP.NET没有魔法——第一个ASP.NET应用《MyBlog》

    创建一个ASP.NET MVC应用程序 在之前文章中介绍了ASP.NET中提供了3个开发动态网页的框架,分别是Web Form.MVC以及Web Pages,也大概介绍了它们的特点. 其中MVC对于其 ...

  3. OOP编程特性综合项目

    package SourceFile; //创建动物类(父类). public abstract class CAnimal {  public boolean mammal;   //是不是哺乳动物 ...

  4. python urllib、urlparse、urllib2、cookielib

    1.urllib模块 1.urllib.urlopen(url[,data[,proxies]]) 打开一个url的方法,返回一个文件对象,然后可以进行类似文件对象的操作.本例试着打开google i ...

  5. 浅谈Java多态

    什么是Java中的多态?又是一个纸老虎的概念,老套路,把它具体化,细分化,先想三个问题(注意,这里不是简单的化整为零,而是要建立在学习一个新概念时的思考框架): 1.这个东西有什么用?用来干什么的?它 ...

  6. VS2010 c/c++ 本地化 emscripten 配置

    配置环境 1.下载emsdk-1.35.0-full-64bit.exe,有VS2010的话直接安装. 2.安装好之后,打开cmd,# emsdk update # emsdk install lat ...

  7. python虚拟环境的安装配置

    安装 使用pip安装     pip install virtualenv 因为已经安装过了,所以显示这样 在这里我想在这里推荐大家以后再安装类库时可以用豆瓣源来安装,速度很快,因为在国内访问 官方p ...

  8. JavaScript正则表达式实例汇总

    本文会持续更新 -------------------------------------------------------------------------------------------- ...

  9. 剖析Prometheus的内部存储机制

    Prometheus有着非常高效的时间序列数据存储方法,每个采样数据仅仅占用3.5byte左右空间,上百万条时间序列,30秒间隔,保留60天,大概花了200多G(引用官方PPT). 接下来让我们看看他 ...

  10. java的windows自动化-自动运行java程序

    那么在一些工具齐全并且已经有了一定的写好的java程序的情况下(环境变量和软件见上一章http://www.cnblogs.com/xuezhezlr/p/7718273.html),如何自动化运行j ...