【发布时间】:2019-10-28 05:59:04
【问题描述】:
我希望在 Linq-to-Entities 中完全模拟 SQL Like 的行为。
我不想使用 StartsWith、EndsWith 或 Contains,当原始查询为:
t_test LIKE '%';
我也不能在 SqlFunctions 中使用 Linq-to-SQL 方法,因为我并不总是在实体上使用 SQL 环境(尤其是在使用模拟 DbContext 测试我的存储库时)。
在我的主要案例中,Entity 被插入到 Oracle SQL 数据库。
到目前为止,我已经在 Where 子句中尝试了这个 lambda(我使用 '*' 作为转义字符而不是 '%'):
x => (testName.StartsWith("*") && testName.EndsWith("*") &&
x.Name.Contains(testName.Replace("*", "")) ||
testName.StartsWith("*") &&
x.Name.EndsWith(testName.Replace("*", "")) ||
testName.EndsWith("*") &&
x.Name.StartsWith(testName.Replace("*", ""))))
实体在以下 Oracle SQL 查询中对此进行翻译:
SELECT
"Extent1"."KEY" AS "KEY",
"Extent1"."NAME" AS "NAME",
FROM "T_NAME" "Extent1"
WHERE ((('*' LIKE '*%') AND ('*' LIKE '%*') AND (( NVL(INSTR("Extent1"."NAME", REPLACE('*', '*', '')), 0) ) > 0)));
不返回任何东西。
任何线索或帮助都会很棒。
【问题讨论】:
-
对于没有经验的人,您能否描述一下 Oracle SQL 在查询
WHERE t_test LIKE '%'时给出的行为,您想模拟哪些行为?Contains()在哪些方面无法模仿LIKE?这个问题纯粹是为了让 LINQ to Objects 表现得像 LINQ to Entities 以便让单元测试通过吗? -
我认为像 this extension 这样的东西可能会做你想做的事。
-
@StriplingWarrior:当然。 Oracle SQL 中的此查询返回整个表。 Contains() 无法模仿 LIKE,因为提供者构建的 SQL 查询(如上所示)没有转换完整的行为(当它应该返回所有内容时它什么也不返回)。但是 Contains() 在 Linq-to-Objects 上下文中工作得很好。你是对的,我需要让我的单元测试通过,这就是我不能使用 Linq-to-SQL 的原因(这也是我不能简单地使用 Regex.IsMatch 的原因)
-
如果查询是为了返回整个表,为什么不完全省略
Where子句? -
我发现对于唯一目的是与数据库交互的类,拥有正确的行为(可通过 Integration 测试验证)比拥有通过 unit 的代码更重要 测试。如果代码在运行时表现不同,测试就没有真正的价值:测试可以通过并给您一种错误的安全感,然后在您实际执行时失败。
标签: c# sql entity-framework linq linq-to-entities