qshpeng 2020-07-26
在 SQLSERVER 里,我们在执行命令的时候我们是可以进行参数化传递的。这个好处主要可以防止注入。
定义接受参数的类:
public class DataParameter
{
public DataParameter()
{
}
public DataParameter(string name,object value)
{
this.Name = name;
this.Value = value;
}
public string Name { get; set; }
public object Value { get; set; }
}我们正常写一个 Where 语句,比如 WHERE Age=23 and name like ‘%delaywu%‘ 。从这句话中我们知道一个where 表达式 是由 表字段名 + 操作符号 + 值 组成的基本操作。
所以我们创建一个方法来构建这样的SQL
private static WhereClip BuildWhereChip(string propertyName, object value, QueryOper op, string paramName=null)
{
if(op !=QueryOper.IsNull && op!=QueryOper.IsNotNull && (value==null || value==DBNull.Value))
{
return null;
}
WhereClip where = new WhereClip();
StringBuilder sbSql = new StringBuilder($"{propertyName}{SqlQueryUtils.ToString(op)}");
if (value !=null && value !=DBNull.Value)
{
if(paramName ==null)
{
paramName = SqlQueryUtils.GetParmName(propertyName);
}
if(paramName.Length>0)
{
sbSql.Append($"@{paramName}");
where.Parameters.Add(new DataParameter(paramName, value));
}
else
{
sbSql.Append($"{value}");
}
}
where.WhereSql = sbSql.ToString();
return where;
}public static string GetParmName(string propertyName)
{
//[a.name]="delaywu"
string paramName = propertyName.Replace("[", "").Replace("]", "");
if(paramName.Contains("."))
{
//name
int lstIdx = paramName.LastIndexOf(‘.‘);
paramName = paramName.Substring(lstIdx + 1).Trim();
}
if(!System.Text.RegularExpressions.Regex.IsMatch(paramName,"^[a-zA-Z1-9_]*$"))
{
return string.Empty;
}
return paramName;
}GetParmName 这个方法主要是 可能在写多表查询的时候出现 a.Name b.age 这类的情况。获得其真实的 字段名称。以及[ ] 这个信息的处理。有了基础的构建方法。我们可以把相关操的符的 WHERE 都可以生成出来了。
public static WhereClip Eq(string propertyName, object value, string paramName = null)
{
return BuildWhereChip(propertyName, value, QueryOper.Eq, paramName);
}
public static WhereClip NotEq(string propertyName, object value, string paramName = null)
{
return BuildWhereChip(propertyName, value, QueryOper.NotEq, paramName);
}
public static WhereClip IsNull(string propertyName)
{
return BuildWhereChip(propertyName, null, QueryOper.IsNull, null);
}
public static WhereClip IsNotNull(string propertyName)
{
return BuildWhereChip(propertyName, null, QueryOper.IsNotNull, null);
}
public static WhereClip StartWith(string propertyName, string value, string paramName = null)
{
return Like(propertyName, value.Replace("%", "[%]").Replace("_", "[_]") + ‘%‘, paramName);
}
public static WhereClip EndsWith(string propertyName, string value, string paramName = null)
{
return Like(propertyName, ‘%‘ + value.Replace("%", "[%]").Replace("_", "[_]"), paramName);
}
public static WhereClip Gt(string propertyName, object value, string paramName = null)
{
return BuildWhereChip(propertyName, value, QueryOper.Gt, paramName);
}
public static WhereClip Lt(string propertyName, object value, string paramName = null)
{
return BuildWhereChip(propertyName, value, QueryOper.Lt, paramName);
}
public static WhereClip Le(string propertyName, object value, string paramName = null)
{
return BuildWhereChip(propertyName, value, QueryOper.Le, paramName);
}
public static WhereClip Ge(string propertyName, object value, string paramName = null)
{
return BuildWhereChip(propertyName, value, QueryOper.Ge, paramName);
}
public static WhereClip Like(string propertyName, string value, string paramName = null)
{
if (string.IsNullOrEmpty(value))
{
return null;
}
return BuildWhereChip(propertyName, value, QueryOper.Like, paramName);
}
public static WhereClip Between(string propertyName, object lo, object hi, string paramName=null)
{
WhereClip where = new WhereClip();
StringBuilder sbSql = new StringBuilder($"{propertyName} between ");
if(paramName==null)
{
paramName = SqlQueryUtils.GetParmName(propertyName);
}
if(propertyName.Length>0)
{
string strParamName1 = paramName + "_pmin";
string strParamName2 = paramName + "_pmax";
sbSql.Append($"@{strParamName1} and @{strParamName2} ");
where.Parameters.Add(new DataParameter(strParamName1, lo));
where.Parameters.Add(new DataParameter(strParamName2, hi));
}
else
{
sbSql.Append($"{lo} and {hi}");
}
where.WhereSql = sbSql.ToString();
return where;
}
public static WhereClip DapperIn<T>(string propertyName,IEnumerable<T>values,string paramName=null)
{
if (values == null || !values.Any())
{
return null;
}
WhereClip where = new WhereClip();
if(paramName==null)
{
paramName = SqlQueryUtils.GetParmName(propertyName);
}
if(paramName.Length>0)
{
where.Parameters.Add(new DataParameter(paramName, values));
where.WhereSql = $"{propertyName} in @{paramName} ";
}
else
{
if(typeof(T).FullName==typeof(string).FullName)
{
string strIn = string.Join<T>("‘,‘", values);
where.WhereSql = $"{propertyName} in ({strIn})";
}
else
{
string strIn = string.Join<T>(",", values);
where.WhereSql = $"{propertyName} in ({strIn})";
}
}
return where;
}
public static WhereClip DapperNotIn<T>(string propertyName, IEnumerable<T> values, string paramName = null)
{
if (values == null || !values.Any())
{
return null;
}
WhereClip where = new WhereClip();
if (paramName == null)
{
paramName = SqlQueryUtils.GetParmName(propertyName);
}
if (paramName.Length > 0)
{
where.Parameters.Add(new DataParameter(paramName, values));
where.WhereSql = $"{propertyName} not in @{paramName} ";
}
else
{
if (typeof(T).FullName == typeof(string).FullName)
{
string strIn = string.Join<T>("‘,‘", values);
where.WhereSql = $"{propertyName} not in (‘{strIn}‘) ";
}
else
{
string strIn = string.Join<T>(",", values);
where.WhereSql = $"{propertyName} not in ({strIn}) ";
}
}
return where;
}上面的代码。我主要说一下 Like 相关的。数据库里面我们经常使用 []来转义特殊的单词。like 中%我们是要转义的,其次_也要的。

测试一下:
