Oracle Linq2Sql странное поведение при сравнении пустой строки - PullRequest
0 голосов
/ 14 декабря 2018

Использование EF6 с драйверами Oracle ver.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 действительноне нуль или только пробел.Первый возвращает ноль.Вот предложения where, сгенерированные этими двумя SQL-запросами:

    ("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 голосов
/ 14 декабря 2018

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

И не проверяет отсутствие пробелов, только то, что значение не равно нулю.

...