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>(T model)
{
string sql = "Insert into {0}({1}) Values({2})";
string table = string.Empty; //表名
List<string> member = new List<string>(); //全部列名
List<string> member_value = new List<string>(); //全部的值
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<Student, Student>> la = n => new Student { name = "李四", matn = 60 }; 我们要生成的sql为 name='李四',math=60,为什么类型是这个可以去看看EF扩展的内容。

  la类型是LambdaExpression,我们要解析的事la.Body 其类型为MemberInitExpression

public static void Main(string[] args)
{
Expression<Func<Student, Student>> la = n => new Student { name = "李四", matn = 60 };
Console.WriteLine(GetExpressStr((MemberInitExpression)(la.Body)));
Console.ReadLine();
}
public static string GetExpressStr(MemberInitExpression exp)
{
string result = string.Empty;
List<string> member = new List<string>();
foreach (MemberAssignment item in exp.Bindings)
{
string update = item.Member.Name + "=" + GetConstantStr((ConstantExpression)item.Expression);
member.Add(update);
}
result = string.Join(",", member);
return result;
}
public static string GetConstantStr(ConstantExpression exp)
{
object vaule = exp.Value;
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();
}
return v_str;
}

调试结果:

  2.where条件

  where条件是最麻烦的地方。之前的只有等于号,而where却有大于,小于,且或等等符号,不过Exresion基类中提供了NodeType 类型为ExpressionType,我们可以获取到对应的运算符。参数类型为

 Expression<Func<Student,bool>>   简单理解where条件是每条数据符合不符合,所以返回值为bool

public static void Main(string[] args)
{
Expression<Func<Student,bool>> la =( n=>n.id > 1 && n.id <100 &&n.name !="张三" && n.matn >=60 && n.id != 50 && n.createTime != null);
Console.WriteLine(DealExpress(la));
Console.ReadLine();
}
public static string DealExpress(Expression exp)
{
if (exp is LambdaExpression )
{
LambdaExpression l_exp = exp as LambdaExpression;
return DealExpress(l_exp.Body);
}
if (exp is BinaryExpression)
{
return DealBinaryExpression(exp as BinaryExpression);
}
if (exp is MemberExpression)
{
return DealMemberExpression(exp as MemberExpression);
}
if (exp is ConstantExpression)
{
return DealConstantExpression(exp as ConstantExpression);
}
if (exp is UnaryExpression)
{
return DealUnaryExpression(exp as UnaryExpression);
}
return "";
}
public static string DealUnaryExpression(UnaryExpression exp)
{
return DealExpress(exp.Operand);
}
public static string DealConstantExpression(ConstantExpression exp)
{
object vaule = exp.Value;
string v_str = string.Empty;
if (vaule == null)
{
return "NULL";
}
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();
}
return v_str;
}
public static string DealBinaryExpression(BinaryExpression exp)
{

string left = DealExpress(exp.Left);
string oper = GetOperStr(exp.NodeType);
string right = DealExpress(exp.Right);
if (right == "NULL")
{
if (oper == "=")
{
oper = " is ";
}
else
{
oper = " is not ";
}
}
return left + oper + right;
}
public static string DealMemberExpression(MemberExpression exp)
{
return exp.Member.Name;
}
public static string GetOperStr(ExpressionType e_type)
{
switch (e_type)
{
case ExpressionType.OrElse: return " OR ";
case ExpressionType.Or: return "|";
case ExpressionType.AndAlso: return " AND ";
case ExpressionType.And: return "&";
case ExpressionType.GreaterThan: return ">";
case ExpressionType.GreaterThanOrEqual: return ">=";
case ExpressionType.LessThan: return "<";
case ExpressionType.LessThanOrEqual: return "<=";
case ExpressionType.NotEqual: return "<>";
case ExpressionType.Add: return "+";
case ExpressionType.Subtract: return "-";
case ExpressionType.Multiply: return "*";
case ExpressionType.Divide: return "/";
case ExpressionType.Modulo: return "%";
case ExpressionType.Equal: return "=";
}
return "";
}

调试结果:

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

http://www.cnblogs.com/linxingxunyan/p/6245396.html

C# Expression 树转化为SQL语句(一)的更多相关文章

  1. C# Expression 树转化为SQL与语句(二)--解决参数问题

    在用Expression解析的的时候碰到一些参数(不是具体的值),会出现这种情况. 在这里我们希望得到的是id=10,而不是id=m_id;那如何来解析这些参数? ================== ...

  2. where条件的lambda转化为sql语句

    网上找的源码,但是博主说有bug 让自己调试.这个是我经过多次修改后的代码,可以直接用 public static class LambdaToSqlHelper { #region 基础方法 #re ...

  3. Hql语句转化为sql语句中文乱码问题

    刚刚学习Hql语句就出现这一的问题,百度半天终于解决了,总结一下解决的方案: 出现中文乱码最可能的原因是hibernate配置文件配置的问题 1.检查url路径是否指定字符集为UTF-8 <pr ...

  4. C#实现把String字符串转化为SQL语句中的In后接的参数

    实现把String字符串转化为In后可用参数代码: public string StringToList(string aa) { string bb1 = "("; if (!s ...

  5. 数据库-转换sql语句

    文章描述:主要说明转换成SQL语句的过程.----必要信息(数据库名,表名,条件)转换成SQL语句 一些界面上数据增删改查的操作往往只需要输入一数据库名,表名,加条件就可以进行数据查询了,在这背后是怎 ...

  6. Django&,Flask&pyrthon原生sql语句 基本操作

    Django框架 ,Flask框架 ORM 以及pyrthon原生sql语句操作数据库 WHAT IS ORM? ORM( Object Relational Mapping) 对象关系映射 , 即通 ...

  7. 【mybatis源码学习】mybatis的sql语句映射

    一.重要的接口和类 org.apache.ibatis.scripting.LanguageDriver //语言驱动org.apache.ibatis.scripting.xmltags.XMLLa ...

  8. mysql5.7执行sql语句报错:In aggregated query without GROUP BY, expression #1 of SELECT list contains nonagg

    mysql5.7执行sql语句报错:In aggregated query without GROUP BY, expression #1 of SELECT list contains nonagg ...

  9. SQL语句中的TOP(expression) [PERCENT] [WITH TIES] 用法

    TOP(expression) [PERCENT] [WITH TIES] expression : 指定返回行数的数值表达式.如果指定了PERCENT,则expression默认转换为FLOAT值, ...

随机推荐

  1. Android app启动耗时分析

    前言 app启动耗时过长的话,无论你的app里面的内容多么丰富有趣,作为一个用户,首先是没有耐心去等待的,如果我是一个用户,我会这样想:这是什么垃圾公司出的什么烂app,再等2s不进来就卸载,黑人问号 ...

  2. C、C++中如何成功嵌入python

    修改lib文件名称,拷贝修改C:\Python27\libs目录下原来的python27.lib为python27_d.lib 包含头文件在C:\Python27\include目录下 包含lib文件 ...

  3. PyQt4的一些问题汇总

    (1)PyQt4获取中文路径名字乱码问题 网址可以参见:http://permalink.gmane.org/gmane.comp.python.chinese/9916 处理方式的代码可以参考如下 ...

  4. ubuntu使用du命令查看一级子目录存储空间大小

    命令如下: ls | xargs du -ksh 可以ls不同的目录以查看不同的目录下的一级子目录大小.直接使用ls为当前目录下的一级子目录大小. 查看其他目录的大小: ls -d dirname/* ...

  5. [Java Performance] JVM 线程调优

    调整线程栈空间 当很缺少内存时,能够调整线程使用的内存. 每一个线程都有一个栈,用来记录该线程的调用栈信息.线程中的栈的默认空间是有OS和JVM的版本号决定的: OS 32-bit 64-bit Li ...

  6. android studio教学视频资源(点开即看)

    android studio教学视频资源(点开即看) 自从Google推出android studio之后.包含github在内的非常多第三方代码库项目很多其它的採用的android studio编译 ...

  7. jenkins部署前端node项目实例

    Jenkins 分发文件用到rsync命令   在 /etc/passwd中 修改 jenkins 为 /bin/bash jenkins:x:494:494:Jenkins Automation S ...

  8. T-sql isnull函数介绍

    今天在给同事调取数据的时候,同事反馈说数据偏少,我仔细检查,发现sql语句条件都正确,逻辑没哪里不对,最后经过仔细排查,才发现问题出在null字段上 表中有一列是允许为null值,比如查询名字不为测试 ...

  9. 电子商务(电销)平台中订单模块(Order)数据库设计明细(转载)

    电子商务(电销)平台中订单模块(Order)数据库设计明细 以下是自己在电子商务系统设计中的订单模块的数据库设计经验总结,而今发表出来一起分享,如有不当,欢迎跟帖讨论~ 订单表 (order)|-- ...

  10. Js日常笔记之数组

    1.Array构造函数有一个很大的问题,就是不同的参数,会导致它的行为不一致,es6好像专门为此对数组有升级 因此,不建议使用new Array生成新数组,直接使用数组字面量[...]是更好的做法. ...