C# IgnoreCase vs ToUpper/ToLower数据库查询

C# IgnoreCase vs ToUpper/ToLower数据库查询,c#,case-sensitive,toupper,tolower,C#,Case Sensitive,Toupper,Tolower,我正在数据库中存储用户名,但希望保留用户名大小写,以便用户可以使用诸如“FooBAR”之类的用户名。 我还希望用户名是唯一的(不管大小写)-“BaR”会导致“BaR”不可用 我认为有三种方法可以做到这一点: 首先,我可以这样查询我的用户表: bool usernameAvailable = !_context.Users.Any(u => String.Equals(u.Username, username, StringComparison.OrdinalIgnoreCase)); 其

我正在数据库中存储用户名,但希望保留用户名大小写,以便用户可以使用诸如“FooBAR”之类的用户名。
我还希望用户名是唯一的(不管大小写)-“BaR”会导致“BaR”不可用

我认为有三种方法可以做到这一点:

首先,我可以这样查询我的用户表:

bool usernameAvailable = !_context.Users.Any(u => String.Equals(u.Username, username, StringComparison.OrdinalIgnoreCase));
其次,我可以将两个用户名转换为大写或小写,如下所示:

username = username.ToUpper();
bool usernameAvailable = !_context.Users.Any(u => u.Username.ToUpper() == username);
第三,我可以在表中创建第二列,存储用户名的大小写版本:

username = username.ToUpper();
bool usernameAvailable = !_context.Users.Any(u => u.UsernameUpper == username);
这将需要数据库中更多的空间,但最容易查询

如有任何见解,将不胜感激


这几乎肯定已经在前面得到了回答,所以请为我指出前面帖子的方向,因为我找不到我要找的东西。

这取决于你的优先级,如果你的应用程序速度快或者使用更少的数据库空间,我想这里的时差是可以忽略的,你应该使用第一种方法


wikipedia上有一篇关于这一困境的文章

这取决于你的优先级,如果你的应用程序速度快还是占用更少的数据库空间,我认为时差是可以忽略的,你应该使用第一种方法


维基百科上有一篇关于这一困境的文章

两者都不是一个好的选择。这个问题非常适合数据库端的简单
唯一索引
,以及用户名列上的不区分大小写的
排序规则。因此,客户机只需执行简单的相等性检查,DB将使用索引查找匹配名称是否存在,如果需要,包括不区分大小写的检查

考虑一下,当您添加新用户(检查重复用户)以及用户尝试登录时(因此您需要检查帐户是否存在),您需要进行这样的检查。在这两种情况下,索引都可以确保用户名所需的唯一性并加快查询速度

对于SQLite的特定情况,可以创建一个不区分大小写的唯一索引,如下所示:

创建表用户(
用户名文本
/*其他栏目在这里*/
唯一(用户名COLLATE NOCASE)
)
除了加快检索速度外,这将防止添加两个仅在大小写上不同的用户名。在客户端,只是不用担心外壳。当用户登录时,只需做一个正常的比较,DB就会匹配它们,即使它们只是大小写不同。对于注册,请立即执行
插入操作
,如果存在大小写差异,DB将放大并拒绝它,您可以从中向用户显示“用户名已使用”消息


另请看这篇文章(我从中得出了基本想法):

两者都不是一个好的选择。这个问题非常适合数据库端的简单
唯一索引
,以及用户名列上的不区分大小写的
排序规则。因此,客户机只需执行简单的相等性检查,DB将使用索引查找匹配名称是否存在,如果需要,包括不区分大小写的检查

考虑一下,当您添加新用户(检查重复用户)以及用户尝试登录时(因此您需要检查帐户是否存在),您需要进行这样的检查。在这两种情况下,索引都可以确保用户名所需的唯一性并加快查询速度

对于SQLite的特定情况,可以创建一个不区分大小写的唯一索引,如下所示:

创建表用户(
用户名文本
/*其他栏目在这里*/
唯一(用户名COLLATE NOCASE)
)
除了加快检索速度外,这将防止添加两个仅在大小写上不同的用户名。在客户端,只是不用担心外壳。当用户登录时,只需做一个正常的比较,DB就会匹配它们,即使它们只是大小写不同。对于注册,请立即执行
插入操作
,如果存在大小写差异,DB将放大并拒绝它,您可以从中向用户显示“用户名已使用”消息


也可以看看这篇文章(我从中得出了基本想法):

应该负责执行这些规则的应该是数据库和数据库管理系统。在客户端这样做只会给您带来问题。那么您使用的是哪种数据库呢?一个简单的技巧可能是将用户名同时存储在大小写版本和小写版本中。使用小写字母作为必须唯一的字母。使用大写字母作为显示内容。许多现代登录系统都有一个“显示名”,可以自由选择。我正在使用EntityFrameworkCore。是的,这是我在第二段代码中概述的方法!EntityFrameworkCore不是DB,DB是sql server、postgresql等等。请注意,第一个查询尤其糟糕,因为EF无法理解您的
StringComparison.OrdinalingOreCase
比较,所以它将整个users表拉入内存并在那里执行比较。应该负责执行此类规则的应该是DB和DBMS。在客户端这样做只会给您带来问题。那么您使用的是哪种数据库呢?一个简单的技巧可能是将用户名同时存储在大小写版本和小写版本中。使用小写字母作为必须唯一的字母。使用大写字母作为显示内容。许多现代登录系统都有一个“显示名”,可以自由选择。我正在使用EntityFrameworkCore。是的,这是我在第二段代码中概述的方法!EntityFrameworkCore不是DB,DB是sql server、postgresql等等。请注意,第一个查询尤其糟糕,因为EF无法理解您的
StringComparison.OrdinalingOreCase
比较,所以它将整个users表拉入内存并在那里执行比较。我很惊讶地听到差异可以忽略不计。我倾向于自己测试一下。有趣的文章,谢谢。和往常一样,你可以自己做一个简单的测试:写一个程序,这个程序需要我多长时间