简体   繁体   English

列表中已存在检查或昵称<User>

[英]Check or nickname already exists in List<User>

I am creating an ASP website with a possibility to register. 我正在创建一个可以注册的ASP网站。

The nickname that visitors choose to register has to be unique. 访问者选择注册的昵称必须是唯一的。

Everytime when an user registers, I select all users from the database, and then I am using a foreach loop to check or username already exists: 每当用户注册时,我从数据库中选择所有用户,然后我使用foreach循环检查或用户名已经存在:

private List<User> listExistingUsers;
listExistingUsers = Database.GetUsers();
foreach (User u in listExistingUsers)
{
    if (u.Nickname == txtNickname.text)
    {
        Error = "Username already in use.";
    }
}

But the code above doesn't work properly. 但上面的代码不能正常工作。 It doesn't check all the items in the list which are read from the database. 它不会检查列表中从数据库中读取的所有项目。 So it is possible to have users with the same usernames, which I don't want. 因此,可以让用户拥有相同的用户名,这是我不想要的。

What can I do to solve this problem? 我该怎么做才能解决这个问题? I read about LINQ, but I think that this is the wrong way of checking usernames with List<> in my opinion. 我读到了LINQ,但我认为在我看来这是用List <>检查用户名的错误方法。 I think this username-check must be done in another way. 我认为这个用户名检查必须以另一种方式完成。

Can you experts help me? 你可以帮助我吗? I could also do this check with a SQL-query, but I would like to do it in c#. 我也可以使用SQL查询进行此检查,但我想在c#中执行此操作。

而不是从DB返回所有用户,将用户名传递给Query /存储过程,让后端进行检查,然后返回状态标志1/0 - 存在/不存在。

if (Database.GetUsers().Select(x => x.Nickname).Contains(txtNickname.Text)) should do what you want. if (Database.GetUsers().Select(x => x.Nickname).Contains(txtNickname.Text))应该做你想要的。

I've condensed everything into a single line so I'll give a quick explanation; 我已将所有内容浓缩成一行,因此我将给出一个快速解释; First I use your Database.GetUsers() method to retrieve the users, then I use select to project the Nickname since that's what we're comparing. 首先,我使用您的Database.GetUsers()方法来检索用户,然后我使用select来生成昵称,因为这是我们正在比较的内容。 If that were to execute on it's own it would result in an IEnumerable<string> with all of the Nicknames. 如果它是自己执行的话,那将导致IEnumerable<string>包含所有的昵称。 From there I use contains to see if that list contains the nickname that (I'm assuming) has been entered in the UI. 从那里我使用contains来查看该列表是否包含在UI中输入的(我假设)的昵称。

You can use Contains operator in order tocheck 你可以使用Contains operator来tocheck

listExistingUsers.Select(x => x.Nickname).Contains(txtNickname.text);

link : http://msdn.microsoft.com/fr-fr/library/bhkz42b3%28v=vs.80%29.aspx 链接: http//msdn.microsoft.com/fr-fr/library/bhkz42b3%28v=vs.80%29.aspx

Remark : You can use Any or count (very expensive last solution) 备注:您可以使用Anycount (非常昂贵的最后解决方案)

Use Any operator. 使用任何运算符。 It checks whether any element of a sequence satisfies some condition. 它检查序列的任何元素是否满足某些条件。 In your case condition is user nickname equals to text in textBox : 在您的情况下,条件是用户昵称等于textBox中的文本

if (Database.GetUsers().Any(u => u.Nickname == txtNickname.Text))
    Error = "Username already in use.";

BTW if you change GetUsers to return IQueryable<User> then check will occur on server side. 顺便说一句,如果您更改GetUsers以返回IQueryable<User>那么将在服务器端进行检查。

Do get a list of NickNames once 得到一次NickNames列表

var nickNames = new List<string>();

for(int i=0;i<listExistingUsers.Count;i++)
{
     nickNames.Add(listExistingUsers.NickName);
}

Then u can simply use 然后你可以简单地使用

if(nickNames.Contains(txtNickname.text))
{
     Error = "Username already in use.";
}

1) Have you verified that Database.GetUsers() is actually returning the full list, with no SQL issues? 1)您是否验证过Database.GetUsers()实际上是否返回完整列表,没有SQL问题?

2) Do you need it to be case-insensitive? 2)您是否需要它不区分大小写?

3) You can use the LINQ to do the query like this: 3)您可以使用LINQ执行以下查询:

if (listExistingUsers.Any(u => string.Equals(u, txtNickname.Text, StringComparison.CurrentCultureIgnoreCase)))
{
   // Process error
}

If Database.GetUsers() return all the users from database, so do not use it! 如果Database.GetUsers()从数据库返回所有用户,那么不要使用它! Imagine if you have already 1000 of users, for each new user it will load all the users, and you will have performance issues. 想象一下,如果您已有1000个用户,则每个新用户都会加载所有用户,并且您将遇到性能问题。

Instead, create a new method that search your database and return only one result, case it exists. 相反,创建一个搜索数据库并仅返回一个结果的新方法(如果存在的话)。 Something like : 就像是 :

private bool Database.UserExists(txtNickname.text) {
      //Your query to database with a where statment looking for the nickname. It could be a LINQ query, or any other way you use in your system.
      //If it brings 1 result, it has to return true. 
 }

I think the most tricky part of your task is to fill the database Correctly. 我认为你的任务中最棘手的部分是正确填充数据库。

Particularly: 尤其:

  • Cut off trailing and ending spaces 切断尾随和结尾空格
  • Decide if the user names should becase sensitive 确定用户名是否应该敏感
  • Make sure that when creating a new user name you do not have the nick already 确保在创建新用户名时您没有昵称

About Loading users and checking: 关于加载用户和检查:

As mentioned above LINQ is the most effective a C# like checking for duplicates ( if (Database.GetUsers().Select(x => x.Nickname).Contains(txtNickname.Text))) 如上所述,LINQ是最有效的C#,如检查重复项(if(Database.GetUsers()。Select(x => x.Nickname).Contains(txtNickname.Text)))

I am more used to writing SQL statements than using LINQ. 我比习惯使用LINQ更习惯于编写SQL语句。 If you've got lots of users SQL will read only the selected ones but I don't know if the LINQ statement above pulls all users into the memory pool or just the one(s) with the same nickname. 如果你有很多用户,SQL将只读取选定的用户,但我不知道上面的LINQ语句是否将所有用户拉入内存池或只是具有相同昵称的用户。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM