postgresql 实体框架核心 - 包含区分大小写还是不区分大小写?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43277868/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Entity Framework core - Contains is case sensitive or case insensitive?
提问by 001
"Contains" in Entity Framework core should equivalent to the SQL %like% operator. Therefore "Contains" should be case insensitive however it is case sensitive! (at least in postgres????)
实体框架核心中的“包含”应等效于 SQL %like% 运算符。因此“包含”应该不区分大小写,但它区分大小写!(至少在 postgres 中????)
The following only outputs a result when the correct casing for keyword is used.
以下仅在使用正确的关键字大小写时输出结果。
context.Counties.Where(x => x.Name.Contains(keyword)).ToList();
What am I doing wrong?
我究竟做错了什么?
回答by DarkUrse
It used to be the case for older versions of EF core. Now string.Contains
is case sensitive, and for exemple for sqlite it maps to sqlite function `instr()' ( I don't know for postgresql).
旧版本的 EF 核心曾经是这种情况。现在string.Contains
区分大小写,例如 sqlite 它映射到 sqlite 函数 `instr()'(我不知道 postgresql)。
If you want to compare strings in a case-insensitive way, you have DbFunctions to do the jobs.
如果您想以不区分大小写的方式比较字符串,您可以使用 DbFunctions 来完成这项工作。
context.Counties.Where(x => EF.Functions.Like(x.Name, $"%{keyword}%")).ToList();
UPDATE to @Gert:
更新到@Gert:
A part of the assumption in the question is incorrect. string.Contains
does NOT convert into a LIKE expression
even though it USED to be the case in ef core versions <= 1.0 (I think).
问题中的部分假设是不正确的。即使在 ef 核心版本 <= 1.0(我认为)中曾经是这种情况,string.Contains
也不会转换为 a LIKE expression
。
- In SQLServer
string.contains
converts intoCHARINDEX()
, in oracleand sqliteintoinstr()
which are case sensitive by default UNLESS db or column collation is defined otherwise ( Again, I don't know for postgresql ). - In all cases
EF.Functions.Like()
converts into a SQLLIKE
expression which is case-insensitive by default unless db or column collation is defined otherwise.
- 在SQLServer的
string.contains
转换为CHARINDEX()
,在预言和源码成instr()
其是除非分贝或列排序规则定义,否则情况下,通过默认敏感(同样,我不知道对PostgreSQL)。 - 在所有情况下,
EF.Functions.Like()
转换为LIKE
默认情况下不区分大小写的 SQL表达式,除非另外定义了 db 或列排序规则。
So yes it all goes down to collation but - correct me if I'm wrong - in a way the code can have an influence on the case-sensitive/insensitive search depending on which one of the above method you use.
所以是的,这一切都归结为整理,但是 - 如果我错了,请纠正我 - 在某种程度上,代码可能会对区分大小写/不敏感的搜索产生影响,具体取决于您使用的上述方法之一。
Now, I might not be completely up to date but I don't think EF core migrations deal with DB collation naturally and unless you've already created the table manually you will end up with the default collation (case-sensitive for sqlite and I honestly don't know for the others).
现在,我可能还没有完全了解最新情况,但我认为 EF 核心迁移不会自然地处理 DB 排序规则,除非您已经手动创建了表,否则最终会使用默认排序规则(对 sqlite 和我区分大小写)老实说不知道其他人)。
Getting back to the original question you have at least 2 options to perform this case-insensitive search if not 3 in a future release :
回到最初的问题,您至少有 2 个选项来执行此不区分大小写的搜索,如果不是未来版本中的 3 个:
- Specify the column collation on creation using DbContext.OnModelCreating() using this trick
- Replace your
string.Contains
byEF.Functions.Like()
- Or wait for a promising feature still in discussion:
EF.Functions.Collate()
function
回答by Stas Boyarincev
My answer will concern NpgSQL.
我的回答将涉及 NpgSQL。
EF.Functions.Like()
in PostgreSQL is case-sensitive, but you can useEF.Functions.ILike()
extension methodlocated inNpgsql.EntityFrameworkCore.PostgreSQL
assembly.If you don't have reference to Entity Framework assembly in place where you build query, you can use combination
ToLower()
andContains()
methods, because Npgsql is abletranslateToLower()
method to correct SQL
EF.Functions.Like()
在 PostgreSQL 中区分大小写,但您可以使用位于assembly 中的EF.Functions.ILike()
扩展方法。Npgsql.EntityFrameworkCore.PostgreSQL
如果您在构建查询的地方没有引用实体框架程序集,您可以使用组合
ToLower()
和Contains()
方法,因为 Npgsql能够转换ToLower()
方法来纠正 SQL
Example:
例子:
context.Counties.Where(x => x.Name.ToLower().Contains(keyword.ToLower())).ToList();
About second method keep in mind: you may have performance problems and may encounter problems associated with encoding.
关于第二种方法,请记住:您可能会遇到性能问题,并且可能会遇到与编码相关的问题。
回答by Kfir Guy
IQueryable.Where
is executed in the database, so it is most likely to be case insensitive.
IQueryable.Where
在数据库中执行,因此很可能不区分大小写。
IEnumerable.Where
uses C# String.Contains
, so it is case sensitive.
IEnumerable.Where
使用 C# String.Contains
,因此区分大小写。
Read this answer: Returning IEnumerable vs. IQueryable
回答by topcool
Just try it :
去尝试一下 :
You can Lower case
field and search value
您可以Lower case
字段和搜索值
context.Counties.Where(x => x.Name.ToLower().Contains(keyword.ToLower())).ToList();
Or you can Upper Case
filed and search value
或者您可以Upper Case
归档并搜索值
context.Counties.Where(x => x.Name.ToUpper().Contains(keyword.ToUpper())).ToList();