首页 > 解决方案 > 比较空字符串时 Oracle Linq2Sql 的奇怪行为

问题描述

将 EF6 与 Oracle 驱动程序版本一起使用。4.122.1.0。我们以两种略有不同的方式实现了基本相同的查询:

var foo1 = _someContext
            .SOME_TABLE
            .AsNoTracking()
            .Where(x => x.SOME_STRING_COLUMN != null && x.SOME_STRING_COLUMN.Trim() != "") //aka string.isnullorwhitespace
            .ToString();

VS:

var foo2 = _someContext
            .SOME_TABLE
            .AsNoTracking()
            .Where(x => x.SOME_STRING_COLUMN != null && x.SOME_STRING_COLUMN.Trim() != string.Empty) //aka string.isnullorwhitespace
            .ToString();

从这两个实现中,当 SOME_STRING_COLUMN 确实不为空或仅空白时,只有第二个实现产生所需的结果。第一个返回null。以下是这两个 sql 查询生成的 where 子句:

    ("Extent1"."SOME_STRING_COLUMN" IS NOT NULL)
AND (
    NOT (
                ( (LTRIM(RTRIM("Extent1"."SOME_STRING_COLUMN"))) = :p__linq__0 )
            AND (
                    (
                        CASE WHEN (LTRIM(RTRIM("Extent1"."SOME_STRING_COLUMN")) IS NULL)
                        THEN 1 ELSE 0 END
                    ) = (CASE WHEN (:p__linq__0 IS NULL) THEN 1 ELSE 0 END)
            )
    )
)

======================================================================

    ("Extent1"."SOME_STRING_COLUMN" IS NOT NULL)
AND (
    NOT (
                ( '' = (LTRIM(RTRIM("Extent1"."SOME_STRING_COLUMN")))      )
            AND ( LTRIM(RTRIM("Extent1"."SOME_STRING_COLUMN")) IS NOT NULL )
    )
)

这是 Oracle 驱动程序中的错误还是我在这里遗漏了一些明显的东西?

标签: oracleentity-frameworklinq-to-sqlentity-framework-6

解决方案


在 Oracle 中,空字符串''是一个NULL值。所以你的第二个陈述:

( '' = (LTRIM(RTRIM("Extent1"."SOME_STRING_COLUMN")))      )

是相同的:

( NULL = (LTRIM(RTRIM("Extent1"."SOME_STRING_COLUMN")))      )

既然NULL = <anything>总是假的,那么:

("Extent1"."SOME_STRING_COLUMN" IS NOT NULL)
AND (
    NOT (
                ( '' = (LTRIM(RTRIM("Extent1"."SOME_STRING_COLUMN")))      )
            AND ( LTRIM(RTRIM("Extent1"."SOME_STRING_COLUMN")) IS NOT NULL )
    )
)

是相同的:

("Extent1"."SOME_STRING_COLUMN" IS NOT NULL)
AND ( NOT ( FALSE AND <anything> ) )

这可以简化为第一个条件:

("Extent1"."SOME_STRING_COLUMN" IS NOT NULL)

并且不测试是否没有空格,只是该值不为空。


推荐阅读