在自己做框架时候遇到一个对条件拼装问题。用lambda写法却无法转换成对象加以组合。直到找到下面这些代码

那么可以直接将lambda表达式解析成SQL条件语句

   WhereClip<Admin_User> where = new WhereClip<Admin_User>(a => a.User_NikeName == "ssdf" || a.User_RegIP == "dddd");where.And(a=>a.User_Email=="dddd");where.And(a => a.User_Name == "dddd");where.Or(a => a.User_Status > 2);

如下

(([User_NikeName] = @User_NikeName) OR ([User_RegIP] = @User_RegIP))AND([User_Email] = @User_Email)AND([User_Name] = @User_Name)AND([User_Status] > @User_Status)

当然我自己加上了参数化了,具体如何写可以适当加以改写

主要代码:

 internal class ConditionBuilder : ExpressionVisitor{private Hashtable m_arguments;private Stack<string> m_conditionParts;public string Condition { get; private set; }public Hashtable Arguments { get; private set; }public void Build(Expression expression){PartialEvaluator evaluator = new PartialEvaluator();Expression evaluatedExpression = evaluator.Eval(expression);this.m_arguments = new Hashtable();this.m_conditionParts = new Stack<string>();this.Visit(evaluatedExpression);this.Arguments = m_arguments;this.Condition = this.m_conditionParts.Count > 0 ? this.m_conditionParts.Pop() : null;}protected override Expression VisitBinary(BinaryExpression b){if (b == null) return b;string opr;switch (b.NodeType){case ExpressionType.Equal:opr = "=";break;case ExpressionType.NotEqual:opr = "<>";break;case ExpressionType.GreaterThan:opr = ">";break;case ExpressionType.GreaterThanOrEqual:opr = ">=";break;case ExpressionType.LessThan:opr = "<";break;case ExpressionType.LessThanOrEqual:opr = "<=";break;case ExpressionType.AndAlso:opr = "AND";break;case ExpressionType.OrElse:opr = "OR";break;case ExpressionType.Add:opr = "+";break;case ExpressionType.Subtract:opr = "-";break;case ExpressionType.Multiply:opr = "*";break;case ExpressionType.Divide:opr = "/";break;default:throw new NotSupportedException(b.NodeType + "is not supported.");}this.Visit(b.Left);this.Visit(b.Right);string right = this.m_conditionParts.Pop();string left = this.m_conditionParts.Pop();string condition = String.Format("({0} {1} {2})", left, opr, right);this.m_conditionParts.Push(condition);return b;}/// <summary>/// 改写 - 加入数据库参数特殊符号 {@}/// </summary>/// <param name="c"></param>/// <returns></returns>protected override Expression VisitConstant(ConstantExpression c){if (c == null) return c;this.m_arguments.Add(m_conditionParts.ToList()[0].Trim('[', ']'), c.Value);this.m_conditionParts.Push(String.Format("{0}", DbFactoryProviderUser.Provider.GetDbParmChar()) + m_conditionParts.ToList()[0].Trim('[',']'));return c;}/// <summary>/// 改写-获取属性特性/// </summary>/// <param name="m"></param>/// <returns></returns>protected override Expression VisitMemberAccess(MemberExpression m){if (m == null) return m;PropertyInfo propertyInfo = m.Member as PropertyInfo;if (propertyInfo == null) return m;this.m_conditionParts.Push(String.Format("[{0}]", propertyInfo.Name));return m;}}
  public abstract class ExpressionVisitor{protected ExpressionVisitor() { }protected virtual Expression Visit(Expression exp){if (exp == null)return exp;switch (exp.NodeType){case ExpressionType.Negate:case ExpressionType.NegateChecked:case ExpressionType.Not:case ExpressionType.Convert:case ExpressionType.ConvertChecked:case ExpressionType.ArrayLength:case ExpressionType.Quote:case ExpressionType.TypeAs:return this.VisitUnary((UnaryExpression)exp);case ExpressionType.Add:case ExpressionType.AddChecked:case ExpressionType.Subtract:case ExpressionType.SubtractChecked:case ExpressionType.Multiply:case ExpressionType.MultiplyChecked:case ExpressionType.Divide:case ExpressionType.Modulo:case ExpressionType.And:case ExpressionType.AndAlso:case ExpressionType.Or:case ExpressionType.OrElse:case ExpressionType.LessThan:case ExpressionType.LessThanOrEqual:case ExpressionType.GreaterThan:case ExpressionType.GreaterThanOrEqual:case ExpressionType.Equal:case ExpressionType.NotEqual:case ExpressionType.Coalesce:case ExpressionType.ArrayIndex:case ExpressionType.RightShift:case ExpressionType.LeftShift:case ExpressionType.ExclusiveOr:return this.VisitBinary((BinaryExpression)exp);case ExpressionType.TypeIs:return this.VisitTypeIs((TypeBinaryExpression)exp);case ExpressionType.Conditional:return this.VisitConditional((ConditionalExpression)exp);case ExpressionType.Constant:return this.VisitConstant((ConstantExpression)exp);case ExpressionType.Parameter:return this.VisitParameter((ParameterExpression)exp);case ExpressionType.MemberAccess:return this.VisitMemberAccess((MemberExpression)exp);case ExpressionType.Call:return this.VisitMethodCall((MethodCallExpression)exp);case ExpressionType.Lambda:return this.VisitLambda((LambdaExpression)exp);case ExpressionType.New:return this.VisitNew((NewExpression)exp);case ExpressionType.NewArrayInit:case ExpressionType.NewArrayBounds:return this.VisitNewArray((NewArrayExpression)exp);case ExpressionType.Invoke:return this.VisitInvocation((InvocationExpression)exp);case ExpressionType.MemberInit:return this.VisitMemberInit((MemberInitExpression)exp);case ExpressionType.ListInit:return this.VisitListInit((ListInitExpression)exp);default:throw new Exception(string.Format("Unhandled expression type: '{0}'", exp.NodeType));}}protected virtual MemberBinding VisitBinding(MemberBinding binding){switch (binding.BindingType){case MemberBindingType.Assignment:return this.VisitMemberAssignment((MemberAssignment)binding);case MemberBindingType.MemberBinding:return this.VisitMemberMemberBinding((MemberMemberBinding)binding);case MemberBindingType.ListBinding:return this.VisitMemberListBinding((MemberListBinding)binding);default:throw new Exception(string.Format("Unhandled binding type '{0}'", binding.BindingType));}}protected virtual ElementInit VisitElementInitializer(ElementInit initializer){ReadOnlyCollection<Expression> arguments = this.VisitExpressionList(initializer.Arguments);if (arguments != initializer.Arguments){return Expression.ElementInit(initializer.AddMethod, arguments);}return initializer;}protected virtual Expression VisitUnary(UnaryExpression u){Expression operand = this.Visit(u.Operand);if (operand != u.Operand){return Expression.MakeUnary(u.NodeType, operand, u.Type, u.Method);}return u;}protected virtual Expression VisitBinary(BinaryExpression b){Expression left = this.Visit(b.Left);Expression right = this.Visit(b.Right);Expression conversion = this.Visit(b.Conversion);if (left != b.Left || right != b.Right || conversion != b.Conversion){if (b.NodeType == ExpressionType.Coalesce && b.Conversion != null)return Expression.Coalesce(left, right, conversion as LambdaExpression);elsereturn Expression.MakeBinary(b.NodeType, left, right, b.IsLiftedToNull, b.Method);}return b;}protected virtual Expression VisitTypeIs(TypeBinaryExpression b){Expression expr = this.Visit(b.Expression);if (expr != b.Expression){return Expression.TypeIs(expr, b.TypeOperand);}return b;}protected virtual Expression VisitConstant(ConstantExpression c){return c;}protected virtual Expression VisitConditional(ConditionalExpression c){Expression test = this.Visit(c.Test);Expression ifTrue = this.Visit(c.IfTrue);Expression ifFalse = this.Visit(c.IfFalse);if (test != c.Test || ifTrue != c.IfTrue || ifFalse != c.IfFalse){return Expression.Condition(test, ifTrue, ifFalse);}return c;}protected virtual Expression VisitParameter(ParameterExpression p){return p;}protected virtual Expression VisitMemberAccess(MemberExpression m){Expression exp = this.Visit(m.Expression);if (exp != m.Expression){return Expression.MakeMemberAccess(exp, m.Member);}return m;}protected virtual Expression VisitMethodCall(MethodCallExpression m){Expression obj = this.Visit(m.Object);IEnumerable<Expression> args = this.VisitExpressionList(m.Arguments);if (obj != m.Object || args != m.Arguments){return Expression.Call(obj, m.Method, args);}return m;}protected virtual ReadOnlyCollection<Expression> VisitExpressionList(ReadOnlyCollection<Expression> original){List<Expression> list = null;for (int i = 0, n = original.Count; i < n; i++){Expression p = this.Visit(original[i]);if (list != null){list.Add(p);}else if (p != original[i]){list = new List<Expression>(n);for (int j = 0; j < i; j++){list.Add(original[j]);}list.Add(p);}}if (list != null){return list.AsReadOnly();}return original;}protected virtual MemberAssignment VisitMemberAssignment(MemberAssignment assignment){Expression e = this.Visit(assignment.Expression);if (e != assignment.Expression){return Expression.Bind(assignment.Member, e);}return assignment;}protected virtual MemberMemberBinding VisitMemberMemberBinding(MemberMemberBinding binding){IEnumerable<MemberBinding> bindings = this.VisitBindingList(binding.Bindings);if (bindings != binding.Bindings){return Expression.MemberBind(binding.Member, bindings);}return binding;}protected virtual MemberListBinding VisitMemberListBinding(MemberListBinding binding){IEnumerable<ElementInit> initializers = this.VisitElementInitializerList(binding.Initializers);if (initializers != binding.Initializers){return Expression.ListBind(binding.Member, initializers);}return binding;}protected virtual IEnumerable<MemberBinding> VisitBindingList(ReadOnlyCollection<MemberBinding> original){List<MemberBinding> list = null;for (int i = 0, n = original.Count; i < n; i++){MemberBinding b = this.VisitBinding(original[i]);if (list != null){list.Add(b);}else if (b != original[i]){list = new List<MemberBinding>(n);for (int j = 0; j < i; j++){list.Add(original[j]);}list.Add(b);}}if (list != null)return list;return original;}protected virtual IEnumerable<ElementInit> VisitElementInitializerList(ReadOnlyCollection<ElementInit> original){List<ElementInit> list = null;for (int i = 0, n = original.Count; i < n; i++){ElementInit init = this.VisitElementInitializer(original[i]);if (list != null){list.Add(init);}else if (init != original[i]){list = new List<ElementInit>(n);for (int j = 0; j < i; j++){list.Add(original[j]);}list.Add(init);}}if (list != null)return list;return original;}protected virtual Expression VisitLambda(LambdaExpression lambda){Expression body = this.Visit(lambda.Body);if (body != lambda.Body){return Expression.Lambda(lambda.Type, body, lambda.Parameters);}return lambda;}protected virtual NewExpression VisitNew(NewExpression nex){IEnumerable<Expression> args = this.VisitExpressionList(nex.Arguments);if (args != nex.Arguments){if (nex.Members != null)return Expression.New(nex.Constructor, args, nex.Members);elsereturn Expression.New(nex.Constructor, args);}return nex;}protected virtual Expression VisitMemberInit(MemberInitExpression init){NewExpression n = this.VisitNew(init.NewExpression);IEnumerable<MemberBinding> bindings = this.VisitBindingList(init.Bindings);if (n != init.NewExpression || bindings != init.Bindings){return Expression.MemberInit(n, bindings);}return init;}protected virtual Expression VisitListInit(ListInitExpression init){NewExpression n = this.VisitNew(init.NewExpression);IEnumerable<ElementInit> initializers = this.VisitElementInitializerList(init.Initializers);if (n != init.NewExpression || initializers != init.Initializers){return Expression.ListInit(n, initializers);}return init;}protected virtual Expression VisitNewArray(NewArrayExpression na){IEnumerable<Expression> exprs = this.VisitExpressionList(na.Expressions);if (exprs != na.Expressions){if (na.NodeType == ExpressionType.NewArrayInit){return Expression.NewArrayInit(na.Type.GetElementType(), exprs);}else{return Expression.NewArrayBounds(na.Type.GetElementType(), exprs);}}return na;}protected virtual Expression VisitInvocation(InvocationExpression iv){IEnumerable<Expression> args = this.VisitExpressionList(iv.Arguments);Expression expr = this.Visit(iv.Expression);if (args != iv.Arguments || expr != iv.Expression){return Expression.Invoke(expr, args);}return iv;}}
public class PartialEvaluator : ExpressionVisitor{private Func<Expression, bool> m_fnCanBeEvaluated;private HashSet<Expression> m_candidates;public PartialEvaluator(): this(CanBeEvaluatedLocally){ }public PartialEvaluator(Func<Expression, bool> fnCanBeEvaluated){this.m_fnCanBeEvaluated = fnCanBeEvaluated;}public Expression Eval(Expression exp){this.m_candidates = new Nominator(this.m_fnCanBeEvaluated).Nominate(exp);return this.Visit(exp);}protected override Expression Visit(Expression exp){if (exp == null){return null;}if (this.m_candidates.Contains(exp)){return this.Evaluate(exp);}return base.Visit(exp);}private Expression Evaluate(Expression e){if (e.NodeType == ExpressionType.Constant){return e;}LambdaExpression lambda = Expression.Lambda(e);Delegate fn = lambda.Compile();return Expression.Constant(fn.DynamicInvoke(null), e.Type);}private static bool CanBeEvaluatedLocally(Expression exp){return exp.NodeType != ExpressionType.Parameter;}#region Nominator/// <summary>/// Performs bottom-up analysis to determine which nodes can possibly/// be part of an evaluated sub-tree./// </summary>private class Nominator : ExpressionVisitor{private Func<Expression, bool> m_fnCanBeEvaluated;private HashSet<Expression> m_candidates;private bool m_cannotBeEvaluated;internal Nominator(Func<Expression, bool> fnCanBeEvaluated){this.m_fnCanBeEvaluated = fnCanBeEvaluated;}internal HashSet<Expression> Nominate(Expression expression){this.m_candidates = new HashSet<Expression>();this.Visit(expression);return this.m_candidates;}protected override Expression Visit(Expression expression){if (expression != null){bool saveCannotBeEvaluated = this.m_cannotBeEvaluated;this.m_cannotBeEvaluated = false;base.Visit(expression);if (!this.m_cannotBeEvaluated){if (this.m_fnCanBeEvaluated(expression)){this.m_candidates.Add(expression);}else{this.m_cannotBeEvaluated = true;}}this.m_cannotBeEvaluated |= saveCannotBeEvaluated;}return expression;}}#endregion}
 public class WhereClip<T> : ExpressionClip where T : BaseEntity
{
public WhereClip()
{
if (table == null)
table = new Hashtable();
}
private String whereString;
public override String WhereString
{
get { return whereString; }
set { whereString = value; }
}
public WhereClip(Expression<Func<T, bool>> exp)
{
if (table == null)
table = new Hashtable();
this.And(exp);
}
private Hashtable table;
public override Hashtable Table
{
get { return table; }
set
{
table = value;
}
}
/// <summary>
/// AND 条件
/// </summary>
/// <param name="right"></param>
public void And(Expression<Func<T, bool>> right)
{
ConditionBuilder conditionBuilder = new ConditionBuilder();
conditionBuilder.Build(right.Body);
if (!String.IsNullOrEmpty(conditionBuilder.Condition))
{
whereString += "AND" + conditionBuilder.Condition;
}
foreach (DictionaryEntry item in conditionBuilder.Arguments)
{
if (!table.ContainsKey(item.Key))
table.Add(item.Key, item.Value);
else
table[item.Key] = item.Value;
}
//替换开始字符
if (whereString.StartsWith("AND"))
{
whereString = WhereString.TrimStart('A', 'N', 'D');
}
}
/// <summary>
/// OR 条件
/// </summary>
/// <param name="right"></param>
public void Or(Expression<Func<T, bool>> right)
{
ConditionBuilder conditionBuilder = new ConditionBuilder();
conditionBuilder.Build(right.Body);
if (!String.IsNullOrEmpty(conditionBuilder.Condition))
{
whereString += "OR" + conditionBuilder.Condition;
}
foreach (DictionaryEntry item in conditionBuilder.Arguments)
{
if (!table.ContainsKey(item.Key))
table.Add(item.Key, item.Value);
else
table[item.Key] = item.Value;
}
if (whereString.StartsWith("OR"))
{
whereString = WhereString.TrimStart('O', 'R');
}
}
public WhereClip<T> Not()
{
throw new Exception("未实现");
}
public abstract class ExpressionClip : IExpressionClip
{
protected Expression _Expression;
public abstract String WhereString
{
get;
set;
}
public abstract Hashtable Table
{
get;
set;
}
}

代码下载地址:

CSDN:http://download.csdn.net/detail/ysq5202121/4251354

老赵:http://www.cnblogs.com/jeffreyzhao/archive/2008/03/05/linq-to-sql-batch-delete-extension.html

拉姆达表达式转对象(太给力啦!)相关推荐

  1. SqlSugar常用查询实例-拉姆达表达式

    SqlSugar支持拉姆达表达式查询,匿名对象参数等,相对还是比较方便好用的. 一.查询列表: //查询列表SqlSugarClient db = SugarContext.GetInstance() ...

  2. java1.8 Lambda拉姆达表达式深入探究

    当我们遇到下面情况时: SingleObj.getInstance().setRunnable(new Runnable() {@Overridepublic void run() {} }); 编译 ...

  3. 拉姆达表达式学习(1)

    我曾经遇到一个项目,项目里面需要经常对一系列的同类型集合进行操作,如对集合进行增加元素,删除集合的指定索引的元素等等. 我们可以使用ArrayList来进行.如 1 ArrayList stringL ...

  4. 一句话学会拉姆达表达式(JAVA)

    LambdaExpress 一 . 理论 1.1 是什么 ​ Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lam ...

  5. C#拉姆达(=)表达式

    前言: 之前小猪曾经分享过自己对C#委托的一点理解 其实在使用委托的过程中我们会大量的使用拉姆达(=>)表达式 介绍: "Lambda表达式"是一个匿名函数,是一种高效的类似 ...

  6. C# 匿名方法和拉姆达表达式

    "` "`代码如下: using System; using System.Collections.Generic; using System.Linq; using System ...

  7. 匿名函数 和 拉姆达表达式

    匿名函数 匿名方法是创建与特定委托实例相关联的未命名代码块的一种方法.可以通过在代码块后面跟上delegate关键字来创建匿名方法. delegate void print();delegate st ...

  8. 拉姆达表达式学习(2)

    本文转载自:http://www.cnblogs.com/zhouji432600/archive/2010/05/30/1747383.html 在.net3.5里面,委托的定义和实现被大大的简化了 ...

  9. 拉姆达表达式 追加 条件判断 ExpressionFuncT, bool

    拉姆达表达式 追加 条件判断 Expression<Func<T, bool>> 2014/11/13 14:47:59  虫虫飞520   程序员俱乐部   我要评论(0) ...

最新文章

  1. 关联查询取更新时间_数据分析之sql复杂查询
  2. wpf BackgroundWorker 的简单用法
  3. 不同阶QAM调制星座图中,符号能量的归一化计算原理
  4. typec扩展坞hdmi没反应_typec扩展坞转hdmi/vga多功能网口usb转换器苹果华为电脑matebook6元优惠券券后价26.8元...
  5. 入门机器学习(十)--课后作业解析-神经网络(Python实现)
  6. 17.立体匹配——更好的效果与挑战,总结_5
  7. php中引入jquery文件_WP模板开发中,怎样给wordpress网站的文章,添加点赞功能?...
  8. strassen矩阵乘法 java_Strassen 矩阵算法 Java 实现
  9. usb 键盘码表_键盘鼠标对应码表-delphi键值
  10. 数据结构题及c语言版4.31答案,数据结构参考题及答案修正版.doc
  11. linux离线依赖包一键安装包,【分享】一键离线安装PetaLinux依赖包
  12. Datalogic得利捷推出最新读码产品及终端应用,全面提升企业工业制造生产力
  13. 华为HCIE认证考试简介
  14. 手动下载VMware Tolls.ISO
  15. Linux下为命令取别名
  16. 公司合伙人股权的进入和退出机制
  17. 认认真真推荐几个一线IT大佬的公众号,值得收藏
  18. 燕十八ajax笔记,燕十八商城笔记资料.doc
  19. Python3.4图片转换素描
  20. /dev/shm虚拟内存打满与inode号爆满

热门文章

  1. 电机学Matlab仿真代码
  2. mysql udf 执行命令_mylab_sys_exec UDF调用mysql外部系统命令(For linux)
  3. matlab怎么调用桌面文件,Matlab界面Desktop操作桌面简介
  4. 深度学习入门之神经网络的学习
  5. Transfomer详解
  6. 106-Latex矩阵过大问题
  7. Verilog编程之乘法器的实现
  8. ubuntu下route命令详解
  9. linux内存双通道,两根内存就是双通道?太年轻
  10. uniapp 收藏功能实现及组件封装