博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linq中小心使用IndexOf
阅读量:6897 次
发布时间:2019-06-27

本文共 2384 字,大约阅读时间需要 7 分钟。

 

我们平常在做字符串的模糊查询时,有可能会用到下面的类似LINQ写法:

string.IsNullOrEmpty() ? true : a.SN.IndexOf(_SN) != -1

 

这条LINQ翻译为SQL如下:

( ( CASE

                 WHEN ( ( @p__linq__1 IS NULL )

                         OR ( ( Cast(Len(@p__linq__1) AS INT) ) = 0 ) ) THEN Cast(1 AS BIT)

                 WHEN ( NOT ( ( -1 = ( ( Cast(Charindex(@p__linq__2, [Extent1].[SN]) AS INT) ) - 1 ) )

                              AND ( ( Cast(Charindex(@p__linq__2, [Extent1].[SN]) AS INT) ) - 1 IS NOT NULL ) ) ) THEN Cast(1 AS BIT)

                 WHEN ( -1 = ( ( Cast(Charindex(@p__linq__2, [Extent1].[SN]) AS INT) ) - 1 ) ) THEN Cast(0 AS BIT)

               END ) = 1 )

 

注意看黄色部分,这条翻译过来的语句出了问题。

 

附:CHARINDEX用法

expression2 中搜索 expression1 并返回其起始位置(如果找到)。搜索的起始位置为 start_location

如果 expression1 expression2 之一为 NULL,并且数据库兼容级别为 70 或更高,则 CHARINDEX 将返回 NULL。如果数据库兼容级别为 65 或更低,则 CHARINDEX 将仅在 expression1 expression2 都为 NULL 时才返回 NULL 值。

如果在 expression2 内找不到 expression1,则 CHARINDEX 返回 0

返回的开始位置从 1 开始,而非从 0 开始。

分析以下几种情况:

 

为空白值的情况

SELECT ( CASE

           WHEN ( ( '123456' IS NULL )

                   OR ( ( Cast(Len('123456') AS INT) ) = 0 ) ) THEN Cast(1 AS BIT)

           WHEN ( NOT ( ( -1 = ( ( Cast(Charindex('123456', '') AS INT) ) - 1 ) )

                        AND ( ( Cast(Charindex('123456', '') AS INT) ) - 1 IS NOT NULL ) ) ) THEN Cast(1 AS BIT)

           WHEN ( -1 = ( ( Cast(Charindex('123456', '') AS INT) ) - 1 ) ) THEN Cast(0 AS BIT)

         END )

 

结果为0

 

表达式2为空值(NULL)的情况

 

SELECT ( CASE

           WHEN ( ( '123456' IS NULL )

                   OR ( ( Cast(Len('123456') AS INT) ) = 0 ) ) THEN Cast(1 AS BIT)

           WHEN ( NOT ( ( -1 = ( ( Cast(Charindex('123456', null) AS INT) ) - 1 ) )

                        AND ( ( Cast(Charindex('123456', null) AS INT) ) - 1 IS NOT NULL ) ) ) THEN Cast(1 AS BIT)

           WHEN ( -1 = ( ( Cast(Charindex('123456', null) AS INT) ) - 1 ) ) THEN Cast(0 AS BIT)

         END )

 

结果为1

 

测试其关键部分

SELECT ( CASE

           WHEN ( NOT(( -1 = ( ( Cast(Charindex('123456', null) AS INT) ) - 1 ) )

                        AND ( ( Cast(Charindex('123456', null) AS INT) ) - 1 IS NOT NULL ) ) ) THEN Cast(1 AS BIT)

         END )

结果为1

 

也就是说,当表中要查找的列中存在空值时,用indexOf会把所有空值列查出来。

 

其原因就是上文所说的黄色部分,注意那个NOT,它放错了位置!

正确方式如下:

SELECT ( CASE

           WHEN ( ( '123456' IS NULL )

                   OR ( ( Cast(Len('123456') AS INT) ) = 0 ) ) THEN Cast(1 AS BIT)

           WHEN ( ( NOT( -1 = ( ( Cast(Charindex('123456', null) AS INT) ) - 1 ) )

                        AND ( ( Cast(Charindex('123456', null) AS INT) ) - 1 IS NOT NULL ) ) ) THEN Cast(1 AS BIT)

           WHEN ( -1 = ( ( Cast(Charindex('123456', null) AS INT) ) - 1 ) ) THEN Cast(0 AS BIT)

         END )

 

结果为NULL

 

结论:

当我们在模糊查询时,如果确定要查的列没有NULL值,可以使用indexOf,否则要考虑其它方式,比如Contains(它翻译的SQLLIKE)。

转载于:https://www.cnblogs.com/wdf2gy/p/4366872.html

你可能感兴趣的文章
mac编辑器vim美化
查看>>
MD5摘要算法简析
查看>>
《30天自制操作系统》学习笔记一
查看>>
Python.tornado.2.tornado.options
查看>>
mysql关于or的索引问题
查看>>
初遇Linux
查看>>
onclick事件没有反应的五种可能情况
查看>>
vue----webpack----对vuex的理解
查看>>
08----mockjs处理前端传来的路径,获取?后面的值
查看>>
蓝桥杯 算法训练 最短路 [ 最短路 bellman ]
查看>>
修改 IIS6.0 时间格式的问题。
查看>>
C# IS 和 AS 的用法和区别
查看>>
软件测试过程中的缺陷密度计算问题
查看>>
图论算法----最短路
查看>>
[备用] 百度地图兴趣点抓取
查看>>
《About Face 3:交互设计精髓》读书笔记(一)
查看>>
invalid derived query的解决办法
查看>>
打印沙漏
查看>>
c#接口
查看>>
"只能在执行Render()的过程中调用RegisterForEventValidation" 解决方案
查看>>