转: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的核心内容。

时间: 2024-12-18 02:38:30

转:C#制作ORM映射学习笔记二 配置类及Sql语句生成类的相关文章

转:C#制作ORM映射学习笔记三 ORM映射实现

现在开始实现ORM的主体模块,首先需要在项目中新建一个类,命名为DbAccess,然后在项目的引用中添加两个dll,分别是MySql.Data.dll和System.Data.SQLite.dll,这两个dll都可以在对应的数据库官网上下载到,为了方便我这里也提供一个下载地址.添加好dll后需要在DbAccess中添加几个名空间,具体代码如下: using System; using System.Collections; using System.Collections.Generic; us

转:C#制作ORM映射学习笔记一 自定义Attribute类

之前在做unity项目时发现只能用odbc连接数据库,感觉非常的麻烦,因为之前做web开发的时候用惯了ORM映射,所以我想在unity中也用一下ORM(虽然我知道出于性能的考虑这样做事不好的,不过自己的小项目吗管他的,自己爽就行了).不过现在世面上的ORM映射基本都是为web项目设计的,与unity项目很难契合,所以我决定自己做一个简易的ORM映射.虽然想的很美但是实际做起来才发现还是挺复杂的,所以我在这里记录一下这次的开发过程,防止以后遗忘. 今天先记录一下如何通过自定义attribute类实

QtSQL学习笔记(3)- 执行SQL语句

QSqlQuery类提供了一个用于执行SQL语句和浏览查询的结果集的接口. QSqlQueryModel和QSqlTableModel类提供了一个用于访问数据库的高级接口,这将在下一节介绍.如果你不熟悉SQL,如果你不熟悉SQL,你可以直接使用下一节介绍的高级接口类. 1 执行一个查询 要执行一个SQL语句,简单的创建一个QSqlQuery对象,然后调用QSqlQuery::exec()方法即可,如下所示: QSqlQuery query; query.exec("SELECT name, sa

Struts2学习笔记二 配置详解

Struts2执行流程 1.简单执行流程,如下所示: 在浏览器输入请求地址,首先会被过滤器处理,然后查找主配置文件,然后根据地址栏中输入的/hello去每个package中查找为/hello的namespace,然后在包下寻找名为HelloAction的action,反射创建控制器HelloAction对象,调用method指定的方法hello,拿到返回值“success”,去result的配置节找success对应的页面(hello.js),呈现给用户. 2.Struts的架构,具体参考这里

Struts2学习笔记(二)——配置详解

1.Struts2配置文件加载顺序: default.properties(默认常量配置) struts-default.xml(默认配置文件,主要配置bean和拦截器) struts-plugin.xml(配置插件) struts.xml(配置action或者常量等) struts.properties(常量配置) web.xml(配置JavaEE,如:监听器和过滤器) 2.Struts2配置文件详解 1)default.properties default.properties是Struts

mysql性能优化学习笔记(3)常见sql语句优化

一.max()优化mysql> explain select max(payment_date) from payment;+----+-------------+---------+------+---------------+------+---------+------+-------+-------+| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows  | Extra |+-

【EF学习笔记03】----------使用原生Sql语句

在EF中使用原生SQL,首先要创建上下文对象 using (var db = new Entities()) { //数据操作 } 新增 string sql = "insert into UserInfo values('zhangsan','123456')"; db.Database.ExecuteSqlCommand(sql); 参数化新增 sql = "insert into UserInfo values(@UserName,@UserPass)"; v

【Unity 3D】学习笔记二十九:游戏实例——简单小地图制作

任何的学习,光看不练是学不好的.所以这次就总结回顾下怎么制作MMROPG类游戏中的小地图.在MMROPG类游戏里,主角在游戏世界里走动时,一般在屏幕右上角都会有一个区域来显示当前游戏场景的小地图.主角在游戏世界里走动,小地图里代表着主角的小标记也会随之移动.那怎么实现咧? 首先需要确定两个贴图,第一个是右上角的小地图背景贴图,应该是从Y轴俯视向下截取主角所在的位置大地图.第二个就是主角的位置大贴图.在本例中,因为没有学习unity地图制作,所以地图用一个面对象代替,主角用立方体代替,使用GUI来

Spring Batch学习笔记二

此系列博客皆为学习Spring Batch时的一些笔记: Spring Batch的架构 一个Batch Job是指一系列有序的Step的集合,它们作为预定义流程的一部分而被执行: Step代表一个自定义的工作单元,它是Job的主要构件块:每一个Step由三部分组成:ItemReader.ItemProcessor.ItemWriter:这三个部分将执行在每一条被处理的记录上,ItemReader读取每一条记录,然后传递给ItemProcessor处理,最后交给ItemWriter做持久化:It