首页 > 其他分享 >NET EF 参数化查询(LIKE / IN)

NET EF 参数化查询(LIKE / IN)

时间:2023-07-20 13:45:04浏览次数:60  
标签:Sort sqlBuilder LIKE EF Value Key var NET SqlParameter

原始数据:

1.拼接SQL:容易注入

2.参数化查询:

2.1.等于 + Like:

2.2.等于 + Like + IN:

2.2.1.结果:类似的参数传递,但是结果为0

2.2.2.分析:通过SQL Server Profile得到运行sql,发现 IN 的参数被处理成了一个字符串,类似于:

WHERE [Key] IN ('''01'', ''11'', ''21'', ''22'', ''23''')

 2.3.IN 的解决方法

2.3.1.LIKE OR CHARINDEX: 网传的骚方法,本质上是,把IN的参数合并为字符串,检索字段是否匹配,容易误判([Key] IN (1,2,3,4))

WHERE @Key LIKE '%''' + [Key] + '''%'
OR
WHERE CHARINDEX('''' + [KEY] + '''', @Key) > 0

PS: 拼接和字段都需要加上分隔符,不然容易误判,比如:001 LIKE '%01%',但结果不是预期

2.3.2.EXEC

exec sp_executesql N'EXEC(''SELECT 1 WHERE 1 IN (''+@Key+'')'')',N'@Key nvarchar(5)',@Key=N'1,2,3'

PS:只适用于INT查询,操作不当容易出现类型错误和语法错误

exec sp_executesql N'EXEC(''SELECT 1 WHERE ''01'' IN (''+@Key+'')'')', N'@Key nvarchar(28),@Value nvarchar(9),@Sort int'
    ,@Key=N'''01'', ''11'', ''21'', ''22'', ''23''',@Value=N'%Value_0%',@Sort=1

语法错误:

Msg 102, Level 15, State 1, Line 51
Incorrect syntax near '01'.

PRINT 'SELECT 1 WHERE ''01'' IN (''+'''01'', ''11'', ''21'', ''22'', ''23'''+'')'

2.3.3.给 IN 集合的值都维护到参数数组中

PS:参数有限制,最大2100,根据实际情况使用

2.3.4.STRING_SPLIT:看了MSSQL抓取的SQL,可以看出 IN 的值在DB中都是字符串,那我把字符串处理成集合就不好啦,没有数量限制还灵活

 

AllCode

        /// <summary>
        /// 参数化查询
        /// </summary>
        [Fact]
        public void TestParamQuery()
        {
            var date = DateTime.Now;
            var date2 = date.AddDays(2).AddHours(17);
            using (var context = new ODMSmartReportEntities())
            {
                context.Database.Log = NLogHelper.Info;

                var sort = 1;
                var value = "Value_0";
                var keyList = new List<string> { "01", "11", "21", "22", "23" };
                var sqlBuilder = new StringBuilder();
                sqlBuilder.AppendLine(" WITH V_ALL AS (");
                sqlBuilder.AppendLine("     SELECT '01' AS [Key], 'Value_01' as [Value], 01 AS [Sort] UNION ALL");
                sqlBuilder.AppendLine("     SELECT '02' AS [Key], 'Value_02' as [Value], 02 AS [Sort] UNION ALL");
                sqlBuilder.AppendLine("     SELECT '03' AS [Key], 'Value_03' as [Value], 03 AS [Sort] UNION ALL");
                sqlBuilder.AppendLine("     SELECT '11' AS [Key], 'Value_11' as [Value], 01 AS [Sort] UNION ALL");
                sqlBuilder.AppendLine("     SELECT '12' AS [Key], 'Value_12' as [Value], 02 AS [Sort] UNION ALL");
                sqlBuilder.AppendLine("     SELECT '13' AS [Key], 'Value_13' as [Value], 03 AS [Sort] UNION ALL");
                sqlBuilder.AppendLine("     SELECT '21' AS [Key], 'Value_21' as [Value], 01 AS [Sort] UNION ALL");
                sqlBuilder.AppendLine("     SELECT '22' AS [Key], 'Value_22' as [Value], 02 AS [Sort] UNION ALL");
                sqlBuilder.AppendLine("     SELECT '23' AS [Key], 'Value_23' as [Value], 03 AS [Sort] UNION ALL");
                sqlBuilder.AppendLine("     SELECT '31' AS [Key], 'Value_31' as [Value], 01 AS [Sort] UNION ALL");
                sqlBuilder.AppendLine("     SELECT '32' AS [Key], 'Value_32' as [Value], 02 AS [Sort] UNION ALL");
                sqlBuilder.AppendLine("     SELECT '33' AS [Key], 'Value_33' as [Value], 03 AS [Sort] ");
                //sqlBuilder.AppendLine(" ), V_KeyList AS (");
                //sqlBuilder.AppendLine("     SELECT * FROM STRING_SPLIT(@Key, ',')");
                //sqlBuilder.AppendLine(" )");
                //sqlBuilder.AppendLine(" SELECT * FROM V_ALL");
                //{
                //    //  参数化查询 - IN: STRING_SPLIT
                //    SqlParameter[] parameters = {
                //        new SqlParameter("@Key", keyList.Join(",")),
                //        new SqlParameter("@Value", $"%{value}%"),
                //        new SqlParameter("@Sort", sort),
                //    };
                //    var sql = $"{sqlBuilder} WHERE[Key] IN (SELECT VALUE FROM V_KeyList) AND [Value] LIKE @Value AND Sort = @Sort";
                //    var result = context.Database.SqlQuery<DictionaryDto>(sql, parameters).ToList();
                //}
                {
                    //  拼接字符串
                    var sql = $"{sqlBuilder} WHERE [Key] IN ('{keyList.Join("', '")}') AND [Value] LIKE '{value}%' AND Sort = {sort}";
                    var result = context.Database.SqlQuery<DictionaryDto>(sql).ToList();
                }
                {
                    //  参数化查询: 等于 + LIKE
                    SqlParameter[] parameters = {
                        new SqlParameter("@Value", $"%{value}%"),
                        new SqlParameter("@Sort", sort),
                    };
                    var sql = $"{sqlBuilder} WHERE [Value] LIKE @Value AND Sort = @Sort";
                    var result = context.Database.SqlQuery<DictionaryDto>(sql, parameters).ToList();
                }
                {
                    //  参数化查询: 等于 + LIKE + IN
                    var keyStr = $"'{keyList.Join("', '")}'";
                    SqlParameter[] parameters = {
                        new SqlParameter("@Key", keyStr),
                        new SqlParameter("@Value", $"%{value}%"),
                        new SqlParameter("@Sort", sort),
                    };
                    var sql = $"{sqlBuilder} WHERE [Key] IN (@Key) AND [Value] LIKE @Value AND Sort = @Sort";
                    var result = context.Database.SqlQuery<DictionaryDto>(sql, parameters).ToList();
                }
                {
                    //  参数化查询 - IN: LIKE + CHARINDEX
                    var keyStr = $"'{keyList.Join("', '")}'";

                    SqlParameter[] parameters = {
                        new SqlParameter("@Key", keyStr),
                        new SqlParameter("@Value", $"%{value}%"),
                        new SqlParameter("@Sort", sort),
                    };
                    var sql = $"{sqlBuilder} WHERE @Key LIKE '%' + [Key] + '%' AND [Value] LIKE @Value AND Sort = @Sort";
                    var result = context.Database.SqlQuery<DictionaryDto>(sql, parameters).ToList();
                }
                {
                    //  参数化查询 - IN: EXEC
                    SqlParameter[] parameters = {
                        new SqlParameter("@Key", "1,2,3"),
                    };
                    var sql = $"EXEC('SELECT 1 WHERE 1 IN ('+@Key+')')";
                    var result = context.Database.SqlQuery<DictionaryDto>(sql, parameters).ToList();
                }
                {
                    //  参数化查询 - IN: 把 in 的参数都维护到参数数组中
                    var paramsList = BuilderList("@Key", keyList);
                    var keyParamsNameList = paramsList.Select(x => x.ParameterName).ToList();
                    SqlParameter[] parameters = {
                        new SqlParameter("@Value", $"%{value}%"),
                        new SqlParameter("@Sort", sort),
                    };
                    paramsList.AddRange(parameters);
                    var sql = $"{sqlBuilder} WHERE[Key] IN ({keyParamsNameList.Join(",")}) AND [Value] LIKE @Value AND Sort = @Sort";
                    var result = context.Database.SqlQuery<DictionaryDto>(sql, paramsList.ToArray()).ToList();
                }
            }

        }

        /// <summary>
        /// 根据参数生产 参数化集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="fieldName"></param>
        /// <param name="valueList"></param>
        /// <returns></returns>
        public List<SqlParameter> BuilderList<T>(string fieldName, List<T> valueList)
        {
            var paramsList = new List<SqlParameter>();
            valueList.ForEach(x => paramsList.Add(new SqlParameter($"{fieldName}_{paramsList.Count}", x)));
            return paramsList;
        }
View Code

 

标签:Sort,sqlBuilder,LIKE,EF,Value,Key,var,NET,SqlParameter
From: https://www.cnblogs.com/CRobot/p/17566410.html

相关文章

  • java执行telnet
    Java执行Telnet的流程在Java中执行Telnet操作,可以通过使用Java的Socket类来实现。下面是整个流程的步骤展示:步骤描述1创建一个Socket对象,并指定Telnet服务器的IP地址和端口号2获取输入输出流,用于与Telnet服务器进行通信3发送命令到Telnet服务器4获取服务器......
  • kubernetes grafana
    KubernetesGrafanaGrafanaisanopen-sourcedatavisualizationandmonitoringtool.Itallowsyoutocreatedashboardsandpanelstovisualizeyourdatainanintuitivemanner.Kubernetesisapopularcontainerorchestrationplatformthathelpsmanagean......
  • Codeforces 1696G - Fishingprince Plays With Array Again
    初读题目可以发现一些性质:每次操作会使整个序列的和减少至多\(X+Y\),因此\(ans\ge\dfrac{\suma_i}{X+Y}\)。对于两个不相邻位置\(a_i,a_j(|i-j|>1)\),每次操作最多使它们的和减少\(\max(X,Y)\)。然后你发现两个限制可以结合在一起使用,稍加思考可以得到一个比较普适的结论:......
  • Codeforces 1446F - Line Distance
    感觉这种类似于让你找第\(k\)大距离的计算几何题其实都挺套路的。二分一个答案\(t\),然后思考一下什么样的点对满足原点到它们的连线的距离\(\let\)。以原点为圆心\(t\)为半径画个圆,然后分情况讨论:如果\((x_i,y_i)\)或\((x_j,y_j)\)在圆内,那么必然符合条件。如果\(......
  • 如何把建的首选项放到AWC中ctx.preferences来获取
    1、获取首选项的方法:ctx.preferences.ABC2、有个问题,你会发现,你新建的首选项ABC,在 ctx.preferences不存在。A、要做多一步操作。把你新建的首选项名称,放到这个首选项AWC_StartupPreferences里面B、做完之后,要在AWC端退出账号,重新登录,才会生效 ......
  • Codeforces 1621H - Trains and Airplanes
    这能3500?对于一组在\(u\)上的询问,考虑每种线路\(x\),假设\(1\tou\)路径上线路\(x\)的长度为\(len\),那么不难发现收罚款的次数只有两种可能:\(\lfloor\dfrac{len}{T}\rfloor\)或者\(\lfloor\dfrac{len}{T}\rfloor+1\),且对于一个\(v\)满足\(z_u=z_v\)且\(v\)在\(u......
  • Unity UGUI的ContentSizeFitter(内容尺寸适应器)组件的介绍及使用
    UnityUGUI的ContentSizeFitter(内容尺寸适应器)组件的介绍及使用1.什么是ContentSizeFitter组件?ContentSizeFitter是UnityUGUI中的一个组件,用于自动调整UI元素的大小,以适应其内容的大小变化。它可以根据内容的大小自动调整UI元素的宽度和高度,确保内容不会被截断或溢出。2.Cont......
  • netcore Identity(一)
    描述asp.netCoreIdentity提供给我们一组工具包和API,能帮助我们应用程序创建授权和认证功能。也可以用它创建账户并使用用户名和密码进行登录,同时也提供了角色和角色管理功能。1.创建项目配置项nuget包Microsoft.AspNetCore.Identity.EntityFrameWorkCoreMicrosoft.Ent......
  • telnet
    telnet登录远程主机和管理(测试ip端口是否连通)补充说明telnet命令用于登录远程主机,对远程主机进行管理。telnet因为采用明文传送报文,安全性不好,很多Linux服务器都不开放telnet服务,而改用更安全的ssh方式了。但仍然有很多别的系统可能采用了telnet方式来提供远程登录,因此弄清......
  • ASP.NET Core 系列总结 -- 系列文章
    《ASP.NETCore》系列文章基于.NET3.1和.NET6,主要是系统总结自己日常工作和学习中的知识点,之前是自己在OneNote上自己写,作为学习、总结笔记,逐渐放出来也供大家参考,希望大家都能够对ASP.NETCore框架有一个清晰的认知。章节目录1.入口文件ASP.NETCore-入口文......