C#编程之C# Expression 树转化为SQL语句(一)
小标 2018-11-14 来源 : 阅读 1115 评论 0

摘要:本文主要向大家介绍了C#编程之C# Expression 树转化为SQL语句(一),通过具体的内容向大家展示,希望对大家学习C#编程有所帮助。

本文主要向大家介绍了C#编程之C#   Expression 树转化为SQL语句(一),通过具体的内容向大家展示,希望对大家学习C#编程有所帮助。

   sql有有四中基本语句,分别是增删改查,在建立model后如何生成这四中sql语句,降低开发时间。
   我们先模拟出一张学生表:

 public class Student
        {
            public int id { get; set; }
            public string name { get; set; }
            public int math { get; set; } //数学成绩
            public DateTime createTime { get; set; }
        }

     首先我们来看看增加,也就是插入语句。插入语句语法比较固定变化少通过泛型和反射可以直接生成。string类型和DateTime类型需要加单引号,其他类型不需要加。
  

public static void Main(string[] args)
        {
            Student stu = new Student
            {
                id = 1,
                name = "张三",
                matn = 59,
                createTime = DateTime.Now

            };
            string sql = CreateInsertSql(stu);
            Console.WriteLine(sql);
            Console.ReadLine();
        }
        public static string CreateInsertSql(T model)
        {
            string sql = "Insert into {0}({1}) Values({2})";
            string table = string.Empty;            //表名
            List member = new List(); //全部列名
            List member_value = new List(); //全部的值
            Type type = typeof(T);
            table = type.Name;
            foreach (PropertyInfo item in type.GetProperties())
            {
                string name = item.Name;
                member.Add(name);
                object vaule = item.GetValue(model);
                string v_str = string.Empty;
                if (vaule is string)
                {
                    v_str = string.Format("‘{0}‘", vaule.ToString());
                }
                else if (vaule is DateTime)
                {
                    DateTime time = (DateTime)vaule;
                    v_str = string.Format("‘{0}‘", time.ToString("yyyy-MM-dd HH:mm:ss"));
                }
                else
                {
                    v_str = vaule.ToString();
                }
                member_value.Add(v_str);
            }
            sql = string.Format(sql, table, string.Join(",", member), string.Join(",", member_value));
            return sql;
        }

调试结果为:
  接下来我们来看看其他三种简单sql 删,改,查。简单的分析一下:
      删除:前面固定(delete from ) + 表名 + where条件
  修改:前面固定(update) +表名 +set + 修改内容+ where条件
  查找(根据model 我们默认查找全部字段): 前面固定(select * from ) + 表名 +where 条件
  从上面可以看出来我们需要3中参数(表名,修改内容,where条件)表名非常简单,可以把类名作为表名,反射一个就可以得到,接下来就是修改内容和where条件,修改内容比较简单格式为 set  a=a_value,b=b_value .........,where 条件较为复杂。
  用Expression 表达式树是受EntityFrame的启发,有些不了解的可以看看EF的一些函数的定义。
  现在就开始使用Expression表达式树来生产这2种sql语句。
  Expression表达式树有一个基类是Expression,然后有非常都的类继承这个类,我们想获取继承类的名称和命名空间的的时候可以用 :obj.GetType().Name 和obj.getType().Namespace来获取,这样便于调试。
  1. update中的修改内容。假设我们要对学生的分数进行修改(改成60,让人及格),还有姓名(就是凑个字段),其他的数据不修改。
  参数类型为: Expression<Func> la = n => new Student { name = "李四", matn = 60 }; 我们要生成的sql为 name=‘李四‘,math=60,为什么类型是这个可以去看看EF扩展的内容。
  la类型是LambdaExpression,我们要解析的事la.Body 其类型为MemberInitExpression

 1   public static void Main(string[] args)
 2         {
 3             Expression<Func> la = n => new Student { name = "李四", matn = 60 };
 4             Console.WriteLine(GetExpressStr((MemberInitExpression)(la.Body)));
 5             Console.ReadLine();
 6         }
 7         public static string GetExpressStr(MemberInitExpression exp)
 8         {
 9             string result = string.Empty;
10             List member = new List();
11             foreach (MemberAssignment item in exp.Bindings)
12             {
13                 string update = item.Member.Name + "=" + GetConstantStr((ConstantExpression)item.Expression);
14                 member.Add(update);
15             }
16             result = string.Join(",", member);
17             return result;
18         }
19         public static string GetConstantStr(ConstantExpression exp)
20         {
21             object vaule = exp.Value;
22             string v_str = string.Empty;
23             if (vaule is string)
24             {
25                 v_str = string.Format("‘{0}‘", vaule.ToString());
26             }
27             else if (vaule is DateTime)
28             {
29                 DateTime time = (DateTime)vaule;
30                 v_str = string.Format("‘{0}‘", time.ToString("yyyy-MM-dd HH:mm:ss"));
31             }
32             else
33             {
34                 v_str = vaule.ToString();
35             }
36             return v_str;
37         }

调试结果:
  2.where条件
  where条件是最麻烦的地方。之前的只有等于号,而where却有大于,小于,且或等等符号,不过Exresion基类中提供了NodeType 类型为ExpressionType,我们可以获取到对应的运算符。参数类型为
  Expression<Func>   简单理解where条件是每条数据符合不符合,所以返回值为bool

  1 public static void Main(string[] args)
  2         {
  3             Expression<Func> la =( n=>n.id > 1 && n.id <100 n.name="" n.matn="">=60 && n.id != 50 && n.createTime != null);
  4             Console.WriteLine(DealExpress(la));
  5             Console.ReadLine();
  6         }
  7         public static string DealExpress(Expression exp)
  8         {
  9             if (exp is LambdaExpression )
 10             {
 11                 LambdaExpression l_exp = exp as LambdaExpression;
 12                 return   DealExpress(l_exp.Body);
 13             }
 14             if (exp is BinaryExpression)
 15             {
 16                 return DealBinaryExpression(exp as BinaryExpression);
 17             }
 18             if (exp is MemberExpression)
 19             {
 20                 return DealMemberExpression(exp as MemberExpression);
 21             }
 22             if (exp is ConstantExpression)
 23             {
 24                 return DealConstantExpression(exp as ConstantExpression);
 25             }
 26             if (exp is UnaryExpression)
 27             {
 28                 return DealUnaryExpression(exp as UnaryExpression);
 29             }
 30             return "";
 31         }
 32         public static string DealUnaryExpression(UnaryExpression exp)
 33         {
 34             return DealExpress(exp.Operand);
 35         }
 36         public static string DealConstantExpression(ConstantExpression exp)
 37         {
 38             object vaule = exp.Value;
 39             string v_str = string.Empty;
 40             if (vaule == null)
 41             {
 42                 return "NULL";
 43             }
 44             if (vaule is string)
 45             {
 46                 v_str = string.Format("‘{0}‘", vaule.ToString());
 47             }
 48             else if (vaule is DateTime)
 49             {
 50                 DateTime time = (DateTime)vaule;
 51                 v_str = string.Format("‘{0}‘", time.ToString("yyyy-MM-dd HH:mm:ss"));
 52             }
 53             else
 54             {
 55                 v_str = vaule.ToString();
 56             }
 57             return v_str;
 58         }
 59         public static string DealBinaryExpression(BinaryExpression exp)
 60         {
 61 
 62             string left = DealExpress(exp.Left);
 63             string oper = GetOperStr(exp.NodeType);
 64             string right = DealExpress(exp.Right);
 65             if (right == "NULL")
 66             {
 67                 if (oper == "=")
 68                 {
 69                     oper = " is ";
 70                 }
 71                 else
 72                 {
 73                     oper = " is not ";
 74                 }
 75             }
 76             return left + oper + right;
 77         }
 78         public static string DealMemberExpression(MemberExpression exp)
 79         {
 80              return exp.Member.Name;
 81         }
 82         public static string GetOperStr(ExpressionType e_type)
 83         {
 84             switch (e_type)
 85             {
 86                 case ExpressionType.OrElse: return " OR ";
 87                 case ExpressionType.Or: return "|";
 88                 case ExpressionType.AndAlso: return " AND ";
 89                 case ExpressionType.And: return "&";
 90                 case ExpressionType.GreaterThan: return ">";
 91                 case ExpressionType.GreaterThanOrEqual: return ">=";
 92                 case ExpressionType.LessThan: return "<";
 93                 case ExpressionType.LessThanOrEqual: return "<=";
 94                 case ExpressionType.NotEqual: return "<>";
 95                 case ExpressionType.Add: return "+";
 96                 case ExpressionType.Subtract: return "-";
 97                 case ExpressionType.Multiply: return "*";
 98                 case ExpressionType.Divide: return "/";
 99                 case ExpressionType.Modulo: return "%";
100                 case ExpressionType.Equal: return "=";
101             }
102             return "";
103         }

调试结果:
这些代码中一些漏洞,仅供大家参考学习,这些代码目前不能接受参数,如n=>n.id==m(int m=1),下一篇将会对Expression表达式树的参数进行解析,欢迎大家指正。

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C#.NET频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程