【发布时间】:2015-03-12 11:45:49
【问题描述】:
背景
我有一个只包含一列的表:名称。 里面只有四行,比如说
| Name |
| test1.com |
| test2.com |
| test3.com |
| test4.com |
问题
如果我查询
var email = "a@test2.com";
Table.Where(x => email.EndsWith(x.Name));
我会得到一个空列表。但是如果我先查询所有行并像这样计算内存中的位置
var email = "a@test2.com";
Table.ToList().Where(x => email.EndsWith(x.Name));
我会得到一个列表,其中只包含正确的 test2.com。
第一个查询生成的 SQL 是
SELECT "Extent1"."Name" AS "Name"
FROM "USER"."Table" "Extent1"
WHERE (( NVL(INSTR(REVERSE(:p__linq__0), REVERSE("Extent1"."Name")), 0) ) = 1)
我尝试将 :p__linq__0 替换为 'a@test2.com' 并在 SQLDeveloper 中运行查询,结果是正确的。
更多信息
如果我将 EndsWith() 更改为 Contains(),问题就会消失。这是为 Contains() 生成的 SQL
SELECT "Extent1"."Name" AS "Name"
FROM "USER"."Table" "Extent1"
WHERE (( NVL(INSTR(:p__linq__0, "Extent1"."Name"), 0) ) > 0)
您知道 EndsWith 或 REVERSE 方法有什么问题吗?
环境
- EF5.0
- .NET4.5
- Oracle11g
- ODP.NET11.2 第 3 版
【问题讨论】:
-
这是一个很好的例子,说明了为什么在直接将 IQueryables 与 SQL 一起使用时我们应该始终检查 SQL EntityFramework Generates。我无法解释为什么它会生成它所生成的 SQL……但是检查我生成的几乎每个 IQueryable 已成为一种常见的做法。
标签: c# linq entity-framework oracle11g odp.net