在将用户插入数据库之前,是否有更好更简单的方法来检查用户是否已注册?我通常做的是使用
我创建注册站点使用asp.net c#和sql-server作为数据库
答案 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;
}
}
}
}
}