Lambda转sql部分代码保存
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部分代码保存的更多相关文章
- 防SQL注入代码(ASP版)
<% Dim Fy_Url,Fy_a,Fy_x,Fy_Cs(),Fy_Cl,Fy_Ts,Fy_Zx '---定义部份 头------ Fy_Cl = 1 '处理方式:1=提示信息,2=转向页面, ...
- Html代码保存为Pdf文件
前段时间Insus.NET有实现了<上传Text文档并转换为PDF>http://www.cnblogs.com/insus/p/4313092.html 和<截取视图某一段另存为部 ...
- 大学站防SQL注入代码(ASP版)
方法1: Replace过滤字符 解决方法:查找login.asp下的<from找到下边的类似username=request.Form(”name”) pass=request.Form(”p ...
- C#与数据库访问技术总结(六)之Command对象创建SQl语句代码示例
Command对象创建SQl语句代码示例 说明:前面介绍了 Command 对象的方法和一些属性,回顾一下 Command对象主要用来执行SQL语句.利用Command对象,可以查询数据和修改数据. ...
- 判断字符串中是否有SQL攻击代码
判断一个输入框中是否有SQL攻击代码 public const string SQLSTR2 = @"exec|cast|convert|set|insert|select|delete|u ...
- 定时任务redis锁+自定义lambda优化提取冗余代码
功能介绍: 我系统中需要跑三个定时任务,由于是多节点部署,为了防止多个节点的定时任务重复执行.所以在定时任务执行时加个锁,抢到锁的节点才能执行定时任务,没有抢到锁的节点就不执行.从而避免了定时任务重复 ...
- 转:Excel导入SQL数据库完整代码
Excel导入SQL数据库完整代码 protected void studentload_Click(object sender, EventArgs e) {//批量添加学生信息 SqlConnec ...
- SQL Server中Table字典数据的查询SQL示例代码
SQL Server中Table字典数据的查询SQL示例代码 前言 在数据库系统原理与设计(第3版)教科书中这样写道: 数据库包含4类数据: 1.用户数据 2.元数据 3.索引 4.应用元数据 其中, ...
- java 连接mysql 和sql server2008代码
这两天用java分别连接mysql和sql server2008代码.刚開始都是有错.如今找到了在 自己机器上成功连接的代码: 1. mysql Class.forName("com.mys ...
随机推荐
- Nexus 私有仓库搭建与 Maven 集成
Nexus 私有仓库搭建与 Maven 集成 |作者:RexFang |出处:http://www.cnblogs.com/rexfang/ |关于作者:Java 程序员一枚 |版权:本文版权归作者和 ...
- poj1014二进制优化多重背包
Dividing Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 53029 Accepted: 13506 Descri ...
- 在ASP.NET Core中如何支持每个租户数据存储策略的数据库
在ASP.NET Core中如何支持每个租户数据存储策略的数据库 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻喷,如觉得我翻译有问题请挪步原博客地址 本博文翻译自: ht ...
- Ubuntu 16.04源码编译安装nginx 1.10.0
一.下载相关的依赖库 pcre 下载地址 http://120.52.73.43/jaist.dl.sourceforge.net/project/pcre/pcre/8.38/pcre-8.38.t ...
- apache、php隐藏http头部版本信息的实现方法
1.apache隐藏头部版本信息,编辑httpd.conf文件,找到: ServerTokens OS ServerSignature On 修改为: ServerTokens ProductOnly ...
- java web Servlet学习笔记-2 请求重定向和请求转发的区别
请求转发与请求重定向的区别 请求重定向和转发 1.请求重定向:浏览器的行为(通过响应对象HttpServletResponse来执行) 特点:可以重新定向访问其他Web应用下的资源 浏览器发出了2次请 ...
- 索引节点inode详解
Inode(index node),索引节点.Linux系统中,分区要进行格式化,创建文件系统.在每个Linux存储设备或存储设备的分区(可以是硬盘,软盘,U盘等)被格式化为ext3文件系统后,一般分 ...
- JavaScript中的面向对象程序设计
本文内容目录顺序: 1.Object概念讲述: 2.面向对象程序设计特点: 3.JavaScript中类和实例对象的创建: 4.原型概念: 5.原型API: 6.原型对象的具体使用:7.深入理解使用原 ...
- win10 UWP 剪贴板 Clipboard
win10 UWP 剪贴板 Clipboard使用Windows.ApplicationModel.DataTransfer.Clipboard 设置文本 DataPackage dataPackag ...
- Java设计模式(四)——再谈观察者模式
在本系列的上一篇文章中,我们讨论了JDK对于观察者模式的一套实现.今天我们将要从另一个角度来探索Tomcat中是如何利用观察者模式加载各个组件.不过今天的任务不是解释Tomcat,所以我会单独把重点抽 ...