string sql = @"INSERT INTO stu VALUES (@id,@name) ";

参数化查询是经常用到的,它可以有效防止SQL注入。但是需要手动去匹配参数@id,@name。数据量大时很繁琐,下面是自动填充SqlParameter列表的实现。

支持泛型,Object和ExpandoObject动态类型

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Dynamic;
namespace Comm
{
/// <summary>
/// 作者:徐晓硕
/// 邮箱:xuxiaoshuo@fang.com
/// 版本:v1.0.0
/// </summary>
public class GetSqlParameters
{
/// <summary>
/// 过滤参数的规则
/// </summary>
private static Regex reg = new Regex(@"@\S{1,}?(,|\s|;|--|\)|$)"); private static char[] filterChars = new char[] { ' ', ',', ';', '-',')' }; /// <summary>
/// 根据sql语句和实体对象自动生成参数化查询SqlParameter列表
/// </summary>
/// <typeparam name="T">实体对象类型</typeparam>
/// <param name="sqlStr">sql语句</param>
/// <param name="obj">实体对象</param>
/// <returns>SqlParameter列表</returns>
public static List<SqlParameter> From<T>(String sqlStr, T obj)
{
List<SqlParameter> parameters = new List<SqlParameter>(); List<string> listStr = new List<string>();
Match mymatch = reg.Match(sqlStr);
while (mymatch.Success)
{
listStr.Add(mymatch.Value.TrimEnd(filterChars).TrimStart('@'));
mymatch = mymatch.NextMatch();
}
Type t = typeof(T); PropertyInfo[] pinfo = t.GetProperties(); foreach (var item in listStr)
{
for (int i = ; i < pinfo.Length; i++)
{
if (item.Equals(pinfo[i].Name, StringComparison.OrdinalIgnoreCase))
{
parameters.Add(new SqlParameter() { ParameterName = "@" + item, Value = pinfo[i].GetValue(obj, null) });
break;
}
else
{
if (i == pinfo.Length - )
{
throw new Exception("查询参数@" + item + "在类型" + t.ToString() + "中未找到赋值属性");
}
}
}
} return parameters;
}
/// <summary>
/// 根据sql语句和实体对象自动生成参数化查询SqlParameter列表
/// </summary>
/// <param name="sqlStr">sql语句</param>
/// <param name="obj">实体对象</param>
/// <returns>SqlParameter列表</returns>
public static List<SqlParameter> From(String sqlStr, object obj)
{
List<SqlParameter> parameters = new List<SqlParameter>(); List<string> listStr = new List<string>();
Match mymatch = reg.Match(sqlStr);
while (mymatch.Success)
{
listStr.Add(mymatch.Value.TrimEnd(filterChars).TrimStart('@'));
mymatch = mymatch.NextMatch();
}
Type t = obj.GetType(); PropertyInfo[] pinfo = t.GetProperties(); foreach (var item in listStr)
{
for (int i = ; i < pinfo.Length; i++)
{
if (item.Equals(pinfo[i].Name, StringComparison.OrdinalIgnoreCase))
{
parameters.Add(new SqlParameter() { ParameterName = "@" + item, Value = pinfo[i].GetValue(obj, null) });
break;
}
else
{
if (i == pinfo.Length - )
{
throw new Exception("查询参数@" + item + "在类型" + t.ToString() + "中未找到赋值属性");
}
}
}
} return parameters;
} /// <summary>
/// 根据sql语句和ExpandoObject对象自动生成参数化查询SqlParameter列表
/// </summary>
/// <param name="sqlStr">sql语句</param>
/// <param name="obj">ExpandoObject对象</param>
/// <returns>SqlParameter列表</returns>
public static List<SqlParameter> From(String sqlStr, ExpandoObject obj)
{
List<SqlParameter> parameters = new List<SqlParameter>(); List<string> listStr = new List<string>();
Match mymatch = reg.Match(sqlStr);
while (mymatch.Success)
{
listStr.Add(mymatch.Value.TrimEnd(filterChars).TrimStart('@'));
mymatch = mymatch.NextMatch();
}
IDictionary<String, Object> dic=(IDictionary<String, Object>)obj; foreach (var item in listStr)
{
int reachCount = ;
foreach (var property in dic)
{
if (item.Equals(property.Key, StringComparison.OrdinalIgnoreCase))
{
parameters.Add(new SqlParameter() { ParameterName = "@" + item, Value = property.Value });
break;
}
else
{
if (reachCount == dic.Count-)
{
throw new Exception("查询参数@" + item + "在类型ExpandoObject中未找到赋值属性");
}
}
reachCount++;
}
}
return parameters;
}
}
}

Demo代码

using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Reflection;
using System.Text;
using Framework.Data;
using System.Data;
using System.Data.SqlClient;
using System.Dynamic;
using Comm;
namespace 数据层
{
class Program
{
static void Main(string[] args)
{ string sql = @"INSERT INTO stu VALUES (@id,@name) "; dynamic wherePart = new ExpandoObject();
wherePart.ID = "";
wherePart.Name = "Test";
List<SqlParameter> listPar2 = GetSqlParameters.From(sql, wherePart);
foreach (var item in listPar2)
{
Console.WriteLine(item.ParameterName + ":" + item.Value);
} Console.ReadKey();
}
}
}

转载:http://blog.csdn.net/xxs77ch/article/details/51513722

SQL参数化查询自动生成SqlParameter列表的更多相关文章

  1. SQL Server镜像自动生成脚本

    SQL Server镜像自动生成脚本 镜像的搭建非常繁琐,花了一点时间写了这个脚本,方便大家搭建镜像 执行完这个镜像脚本之后,最好在每台机器都绑定一下hosts文件,不然的话,镜像可能会不work 1 ...

  2. SQL参数化查询

    参数化查询(Parameterized Query 或 Parameterized Statement)是指在设计与数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数 (Parameter) ...

  3. SQL 参数化查询 应用于 Like

    在sql 进行参数化查询的时候,使用like 语句和参数的时候,错误的写法:  Participant like '%@Participant%' ,这样在数据库为解析为 '%'participant ...

  4. sql 参数化查询问题

    一.正确案例 string name=“梅”; string sql="select * from test where  Name  like @Name"; //包含 梅Sql ...

  5. sql 参数化查询

      在初次接触sql时,笔者使用的是通过字符串拼接的方法来进行sql查询,但这种方法有很多弊端 其中最为明显的便是导致了sql注入. 通过特殊字符的书写,可以使得原本正常的语句在sql数据库里可编译, ...

  6. SQL参数化查询--最有效可预防SQL注入攻击的防御方式

    参数化查询(Parameterized Query 或 Parameterized Statement)是访问数据库时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值. 在使用参 ...

  7. SQL参数化查询的问题

    最近碰到个问题, SQL语句中的 "... like '%@strKeyword%'"这样写查不出结果, 非的写成 "... like '%" + strKey ...

  8. mybatis的sql参数化查询

    我们使用jdbc操作数据库的时候,都习惯性地使用参数化的sql与数据库交互.因为参数化的sql有两大有点,其一,防止sql注入:其二,提高sql的执行性能(同一个connection共用一个的sql编 ...

  9. 查询自动生成Guid列

    --newid()可以在查询的时候自动生成Guid列 ' ordey by Random --创建对应的列 用 uniqueidentifier 类型 IF NOT EXISTS ( SELECT * ...

随机推荐

  1. 初识cache

    1.cache是什么 cache这个名字用来称呼两种物理世界中存在的概念,硬体cache和cache机制.下面来分别介绍. 硬体cache:硬体cache是一种用肉眼可以看得见用皮肤可以摸得着的物品, ...

  2. [转]C语言SOCKET编程指南

    1.介绍 Socket编程让你沮丧吗?从man pages中很难得到有用的信息吗?你想跟上时代去编Internet相关的程序,但是为你在调用 connect() 前的bind() 的结构而不知所措?等 ...

  3. Java并发之CountDownLatch

    CountDownLatch是Java concurrent包下的一个同步工具.它可以让一个(或多个)线程等待,直到其他线程中的某些操作完成. 本质上是一个信号量,我们把它比作一个有N个插销的大门,它 ...

  4. sql注入的基本防范手段

    基本的sql注入防御手段,概括来讲就是权限控制和关键词过滤. 防御sql注入 ============================================================= ...

  5. 第二天-uboot学习

    源码阅读方法1.源码目录结构2.配置(支持当前使用的硬件)3.编译(Makefile)4.启动流程 工具使用1.在同一文件查找 shitf+8 N n进行上下查找 2.在工程目录中 ctags ubo ...

  6. [原创]Matlab2016b打包为C++的lib文件

    这几天在研究如何将Matlab的程序导入到C++进行调用. 由于需要使用到不少Matlab函数,所以之前就有些担心这些函数在导出后是否能够继续使用.不过之后觉得既然已经导出成了一个单独文件,相关运算应 ...

  7. SQLServer日期函数用法

    --1.显示本月第一天 ,) ),)) --2.显示本月最后一天 ,),,))) ,,,)) --3.上个月的最后一天 ,,)) --4.本月的第一个星期一 , ) --5.本年的第一天 ,) --6 ...

  8. java基础知识(十一)java反射机制(上)

    java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...

  9. 原子类java.util.concurrent.atomic.*原理分析

    原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...

  10. java基础 布局管理器

    概念: 组建在容器(比如JFrame)中的位置和 大小 是由布局管理器来决定的.所有的容器都会使用一个布局管理器,通过它来自动进行组建的布局管理. 种类: java共提供了物种布局管理器:流式布局管理 ...