Can someone explain why if I run this expression:
const string testValue = "ABC";
return NameDbContext.MasterNames
.Where(m => m.Names.Any(n => n.LastName == testValue))
.ToList();
I get the expected result, however if I run the same with testValue
as a variable it fails:
string testValue = "ABC";
return NameDbContext.MasterNames
.Where(m => m.Names.Any(n => n.LastName == testValue))
.ToList();
This seems to happen only with string
. Similar code with int
worked fine with both testValue
as a variable or as a constant.
I am suspecting this is due to the object nature of string. If this is the case how could I call this expression with a variable (I don't know the value of testValue
at compile time).
Thank you.
EDIT:
This query is run against a large oracle data table (> 6 million rows). When using a constant it returns right away with the proper result set. When running with the variable, it seems that the where
is applied very inefficiently (it takes over a minute to return).
EDIT2:
Tracing queries in the database I see:
When calling with a constant:
SELECT *
FROM (SELECT "Filter2"."MALPHA_KEY" AS "MALPHA_KEY"
FROM (SELECT "Extent1"."MALPHA_KEY" AS "MALPHA_KEY",
ROW_NUMBER () OVER (ORDER BY "Extent1"."MALPHA_KEY" ASC)
AS "row_number"
FROM "RMS"."ALPHA_MASTER_NAME" "Extent1"
WHERE (EXISTS (
SELECT 1 AS "C1"
FROM "RMS"."ALPHA" "Extent2"
WHERE ( ("Extent1"."MALPHA_KEY" =
"Extent2"."MALPHA_KEY"
)
AND ('ABC' = "Extent2"."LAST_NAME")
))
)) "Filter2"
WHERE ("Filter2"."row_number" > 0)
ORDER BY "Filter2"."MALPHA_KEY" ASC)
WHERE (ROWNUM <= (50))
When calling with a variable:
SELECT *
FROM (SELECT "Project2"."MALPHA_KEY" AS "MALPHA_KEY"
FROM (SELECT "Project2"."MALPHA_KEY" AS "MALPHA_KEY",
ROW_NUMBER () OVER (ORDER BY "Project2"."MALPHA_KEY" ASC)
AS "row_number"
FROM (SELECT "Extent1"."MALPHA_KEY" AS "MALPHA_KEY"
FROM "RMS"."ALPHA_MASTER_NAME" "Extent1"
WHERE (EXISTS (
SELECT 1 AS "C1"
FROM "RMS"."ALPHA" "Extent2"
WHERE ( ("Extent1"."MALPHA_KEY" =
"Extent2"."MALPHA_KEY"
)
AND ( ("Extent2"."LAST_NAME" =
:p__linq__0
)
OR ( ("Extent2"."LAST_NAME" IS NULL
)
AND (:p__linq__0 IS NULL
)
)
)
))
)) "Project2") "Project2"
WHERE ("Project2"."row_number" > 0)
ORDER BY "Project2"."MALPHA_KEY" ASC)
WHERE (ROWNUM <= (50))
Note the difference in the where statement (beside the use of a variable) it tests for NULL equality
AND ( ("Extent2"."LAST_NAME" = :p__linq__0
)
OR ( ("Extent2"."LAST_NAME" IS NULL )
AND (:p__linq__0 IS NULL ) ) )
The test for the NULL is resulting in the full table scans...