转:C#制作ORM映射学习笔记二 配置类及Sql语句生成类
在正式开始实现ORM之前还有一点准备工作需要完成,第一是实现一个配置类,这个很简单的就是通过静态变量来保存数据库的一些连接信息,等同于.net项目中的web.config的功能;第二需要设计实现一个sql语句的生成类来帮助生成sql语句,当前如果不实现这个类也不会影响orm的制作,之所以要做这么一个类主要有几个目的,1.减少sql语句中拼写错误的发生。2.统一解决防sql注入的问题。
下面分别说明一下这两个类的实现方式:
1.配置类DbConfig
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ORM { public class DbConfig { /// <summary> /// 数据库连接信息 /// </summary> public static string Host = "D:/C#/ORM/test.db"; /// <summary> /// 数据库类型 /// </summary> public static DbType Type = DbType.Sqlite; } public enum DbType { Sqlite, Mysql, SqlServer, Oracle } }
2.sql语句的生成类Sql
using System; using System.Collections; using System.Text.RegularExpressions; namespace ORM { public class Sql { /// <summary> /// sql语句 /// </summary> private string sql; /// <summary> /// 是否有where关键字 /// </summary> private bool hasWhere; /// <summary> /// 是否有order关键字 /// </summary> private bool hasOrder; /// <summary> /// 防sql注入 /// </summary> /// <param name="value"></param> /// <returns></returns> public static bool InjectionDefend(string value) { //网上随便找的,不确定是否有效 string SqlStr = @"and|or|exec|execute|insert|select|delete|update|alter|create|drop|count|\/\*|\*\/|chr|char|asc|mid|substring|master|truncate|declare|xp_cmdshell|restore|backup|net +user|net +localgroup +administrators"; try { if ((value != null) && (value != String.Empty)) { //string str_Regex = @"\b(" + SqlStr + @")\b"; Regex Regex = new Regex(SqlStr, RegexOptions.IgnoreCase); if (true == Regex.IsMatch(value)) { return false; } } } catch { return false; } return true; } /// <summary> /// 构造函数 /// </summary> public Sql() { sql = string.Empty; hasWhere = false; hasOrder = false; } /// <summary> /// 添加select /// </summary> /// <param name="column"></param> /// <returns></returns> public Sql Select(string column) { sql += ("SELECT " + column + " "); return this; } /// <summary> /// 添加from /// </summary> /// <param name="Table"></param> /// <returns></returns> public Sql From(string Table) { sql += ("FROM " + Table + " "); return this; } /// <summary> /// 添加where /// </summary> /// <param name="query"></param> /// <param name="values"></param> /// <returns></returns> public Sql Where(string query, params object[] values) { if (!hasWhere) { sql += "WHERE "; hasWhere = true; } else { sql += " AND "; } for (int i = 0; i < values.Length; i++) { Regex r = new Regex(@"@\d+"); //bool类型需要特殊处理,不能直接用tostring转换,因为直接转换的结果为"True"或"False",而不是1和0 if (values[i] is bool) { bool value = bool.Parse(values[i].ToString()); query = r.Replace(query, (value ? "1" : "0"), 1); continue; } else if (values[i].GetType().IsPrimitive) { query = r.Replace(query, values[i].ToString(), 1); continue; } else if (values[i].GetType().IsEnum) { int intValue = (int)values[i]; query = r.Replace(query, intValue.ToString(), 1); continue; } else { if (InjectionDefend(values[i].ToString())) { query = r.Replace(query, "\"" + values[i].ToString() + "\"", 1); } } } sql += query; return this; } /// <summary> /// 在sql尾部插入任意sql语句 /// </summary> /// <param name="sql"></param> /// <returns></returns> public Sql Append(string sql, params object[] values) { for (int i = 0; i < values.Length; i++) { Regex r = new Regex(@"@\d+"); if (values[i] is bool) { bool value = bool.Parse(values[i].ToString()); sql = r.Replace(sql, (value ? "1" : "0"), 1); continue; } else if (values[i].GetType().IsPrimitive) { sql = r.Replace(sql, values[i].ToString(), 1); continue; } else if (values[i].GetType().IsEnum) { int intValue = (int)values[i]; sql = r.Replace(sql, intValue.ToString(), 1); continue; } else { if (InjectionDefend(values[i].ToString())) { sql = r.Replace(sql, "\"" + values[i].ToString() + "\"", 1); } } } this.sql += (" " + sql + " "); return this; } /// <summary> /// 添加order /// </summary> /// <param name="column"></param> /// <returns></returns> public Sql OrderBy(string column) { if (!sql.EndsWith(" ")) { sql += " "; } if (hasOrder) { sql += (", " + column); } else { sql += ("ORDER BY " + column); } return this; } /// <summary> /// 获取当前完整的sql语句 /// </summary> /// <returns></returns> public string GetSql() { return sql; } } }
到这里ORM的前期准备工作就完成了,当然Sql实现的非常简单,像inner join、left join等sql语句的帮助生成函数都没有做,但是实现原理时相同的,如果需要可以自己仿照实现,当然也可以直接用Append函数添加sql语句,下篇开始正式介绍ORM的核心内容。
看云吧 kanyun8.com