在插入数据库之前检查用户是否已存在的最佳方法

时间:2015-04-10 10:00:45

标签: c# sql asp.net sql-server

在将用户插入数据库之前,是否有更好更简单的方法来检查用户是否已注册?我通常做的是使用

  • 选择要比较的查询
  • 然后是IF声明
  • 如果TRUE,则msgbox显示“用户已注册”
  • ELSE插入数据库

我创建注册站点使用asp.net c#和sql-server作为数据库

3 个答案:

答案 0 :(得分:2)

尝试使用类似的程序......

CREATE PROCEDURE usp_insert_user
 @Username  VARCHAR(20)
,@Action    VARCHAR(50) OUTPUT
,@UserID    INT         OUTPUT
AS
BEGIN
  SET NOCOUNT ON;

  IF NOT EXISTS(SELECT 1 FROM dbo.[User_Table] WHERE UserName = @Username)
      BEGIN
         INSERT INTO dbo.[User_Table] (UserName)
         VALUES (@Username)

         SET @UserID = SCOPE_IDENTITY();
         SET @Action = 'a new user with Username = ' + @Username + ' has been added'
      END
  ELSE
      BEGIN
        SET @Action = 'a user with Username = ' + @Username + ' already exists'
      END 
END

答案 1 :(得分:0)

这是最好的方法。 但是如果你在多线程环境中工作,你必须做很少的修改。

或者将select修改为select for update。 或者尝试捕获插入,如果有插入错误处理它。

请勿在未经测试的情况下插入并检查是否抛出异常。不是一个好的编程习惯。例外是......名称所说的异常,而不是处理你知道可能抛出的错误的标准方法。

答案 2 :(得分:-2)

以下是如何在代码中执行此操作的现代示例。

正如我在评论中所概述的那样,为什么你应该在代码中而不是在数据库上执行此操作有几个原因,即使数据库选项看起来更具吸引力。

答:这是业务逻辑“不允许多个用户拥有相同的用户名”。数据层不应该关心这一点,只需要存储和检索用户

B:单元测试是世界上最重要的事情。您需要能够以无状态的方式测试您的业务逻辑。能够注入模拟的存储库可以实现这一点。

C:应用程序不应该关注如何实现数据存储。您需要能够将该DB切换为Web服务或设备上的本地存储等。

D:数据库是应用程序基础结构的一部分。如果你变大,你需要有多个,故障转移,群集,复制,备份,测试盒,UAT等等,每个都可能在任何给定的时间运行不同版本的应用程序。在数据库中使用此逻辑可以更难以部署和管理该基础架构

E:数据库不易扩展,是共享资源。考虑这种逻辑变得更复杂的情况。 “当使用用户名时,做一些硬数学”你有一个100台机器的网络农场都在运行你的应用程序,数百万用户试图每秒注册。有了代码中的逻辑,你就有100个便宜的网箱分担了解决硬盘的负担。您可以通过添加更多Web框来扩展。使用DB上的逻辑,您的昂贵数据库盒在其32核CPU上最大化而不回答查询

using System;
using System.Data.SqlClient;
using System.Transactions;

namespace UnitTestProject2
{
    public class User {
        public String Username {get;set;}
    }

    public interface IRepository
    {
        void AddUser(User user);
        bool IsUsernamefree(User user);
    }

    public class RepositorySql : IRepository
    {
        SqlConnection conn;
        public void AddUser(User user)
        {
            SqlCommand cmd = new SqlCommand("insert into users (username) values (@usernane)", conn);
            cmd.Parameters.AddWithValue("@username", user.Username);
            cmd.ExecuteNonQuery();
        }

        public bool IsUsernamefree(User user)
        {
            SqlCommand cmd = new SqlCommand("select count(*) from users where username= @usernane", conn);
            cmd.Parameters.AddWithValue("@username", user.Username);
            object result = cmd.ExecuteScalar();
            if ((int)result == 0)
            {
                return true;
            }
            return false;
        }
    }

    public class UserRegistrationViewModel
    {
        private IRepository rep;

        public string ErrorMessage {get;set;}

        public UserRegistrationViewModel(IRepository rep)
        {
            this.rep = rep;
        }

        public bool RegisterUser(User user)
        {
            using (TransactionScope trans = new TransactionScope())
            {
                if (rep.IsUsernamefree(user))
                {
                    rep.AddUser(user);
                    ErrorMessage = "";
                    return true;
                }
                else
                {
                    ErrorMessage = "the user is not free";
                    return false;
                }
            }
        }
    }
}