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. Event Loop个人理解

    javascript引擎单线程程序,其执行同步操作会按顺序向下执行,执行异步操作则使用事件循环模型. js引擎线程遇到异步操作,会将异步操作交给对应的观察者, 异步操作包括: dom事件 click, ...

  2. Xcode6新特性(1)-删除Main.storyboard

    当新建完一个空项目的时候,Xcode会自动创建一个Main.storyboard的空文件,如果不需要,可以将其删除.但是如果删除,再次运行程序,程序会报错,提示找不到Main.storyboard文件 ...

  3. nio

    1.I/O 输入输出流 (1) 指的是计算机与外界,或者程序与计算机之间数据交换的接口. (2) 在java编程中,使用 流(Stream) 的方式完成I/O , 所有的I/O都被视为单个字节的移动. ...

  4. my97中文乱码问题

    在使用my97日期插件后页面显示中文乱码问题: 解决方法: 把下面这段代码复盖到你的ZH-CN.js就解决了 var $lang={ errAlertMsg: "\u4E0D\u5408\u ...

  5. 在布局中使用android.support.v4.app.Fragment的注意事项

    1.Activity必须继承android.support.v4.app.FragmentActivity 2.fragment标签的name属性必须是完全限定包名,如下: <LinearLay ...

  6. ES5新语法forEach和map及封装原理

    ### forEach 在es5中提供了forEach方法进行遍历,其实就是模仿了jQuery中each方法,不过将 i 于v进行了调换,下面两种方法进行对比一下 var arr = [ 11, 22 ...

  7. js_事件委托

    起因: 1.这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的: 2.其实我一直都没弄明白,写这个一是为了备忘,二是给其他的知其然不知其所以然的小伙伴们以参考: 概述: 那什么叫事件委托呢?它 ...

  8. ACID属性区别

    事务是指对系统进行的一组操作,为了保证系统的完整性,事务需要具有ACID特性,具体如下: 1. 原子性(Atomic)     一个事务包含多个操作,这些操作要么全部执行,要么全都不执行.实现事务的原 ...

  9. 在js中获取在css中设置的background-image值

    1. html部分 <div class="bg-color-two" id="bg_color_two" onclick="setBg(thi ...

  10. C# 反射

    //转载:http://blog.csdn.net/educast/article/details/2894892 反射(Reflection) 在.NET中的反射可以实现从对象的外部来了解对象(或程 ...