我正在编写一种方法,将自定义语言查询转换为Expression
树,以便它可以与任意集合上的Where
扩展方法一起使用。这些集合可以是内存列表中的IEnumerable<T>
,也可以是IQueryable<T>
来进行数据库查询。
我的过滤器逻辑涉及大量字符串包含检查,以检查搜索到的字符串是否出现在每个对象实例的某些属性中。我现在正在使用对string.Contains
的标准调用,对于SQL Server(以及可能还有其他人),它应转换为SQL LIKE '%...%'
,这在大多数数据库系统中应该不区分大小写。默认。但是该方法的.NET实现还有其他功能:它区分大小写,并且会从集合中返回其他(较少)对象,因为它是一种限制性更强的比较。
我花了几个小时的时间来查找和阅读这个主题。 ToLower
和ToUpper
无法正常工作&#34;正确&#34;在Turkey。 SQL生成是否支持ToLowerInvariant
? IndexOf
听起来像是一个更好的选择。 string.Contains
在内部调用string.IndexOf
。 IndexOf
有另一个接受StringComparison
值的重载。但这会支持SQL生成吗?如果我指定Ordinal
而不是OrdinalIgnoreCase
,它将如何翻译?
这一切都非常令人沮丧。数据库与.NET中的内存对象不同。但毕竟,Entity Framework合并了两个世界并将数据库查询直接带入C#。如果常见操作的语义根据它们在运行时的执行方式而发生变化,则会导致各种错误。
答案 0 :(得分:2)
这个问题没有普遍接受的一般解决方案。不幸的是,你必须知道自己在做什么以及在做什么。
核心原因是SQL Server与处理这类查询的方式不一致。它与一致的配置一致,但在.NET环境中某些配置并不为人所知。
在没有实际运行该查询的情况下,没有一般方法可以了解SELECT * FROM users WHERE name LIKE '%foo'
。
最好的解决方案是避免尝试在本地运行查询,只需总是调用数据库。