比较空字符串时,Oracle Linq2Sql的行为很奇怪

时间:2018-12-14 14:26:33

标签: oracle entity-framework linq-to-sql entity-framework-6

将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或仅空白时,仅第二个实现了所需的结果。第一个返回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驱动程序中的错误还是我在这里缺少明显的东西?

1 个答案:

答案 0 :(得分:0)

在Oracle中,空字符串id是一个''值。所以你的第二条语句:

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> ) )

并且不测试是否存在空白,只是该值不为空。