#c# #winforms
#c# #winforms
Вопрос:
я просто хочу проверить, существует ли этот пользователь или нет, и если нет, то сохранить в базе данных, чтобы показать, что пользователь с сообщением об ошибке уже существовал до того, как я использовал эту команду, работает отлично
SqlCommand cmd = new SqlCommand("Select count(*) from cntc_employee where emp_alias= @alias", con);
cmd.Parameters.AddWithValue("@alias", this.alias.Text);
con.Open();
if(Convert.ToInt32(cmd.ExecuteScalar()) > 0)
{
errorProvider1.SetError(alias,"Alias Already exist");
return true;
}
else
{
return false;
}
но на 3-м уровне я не знаю, как использовать executescalar в моем классе bll в разделе if ()
в моем классе bll
private bool UserNameCheck(string alias)
{
if (??)
throw new Exception("Alias Already exist");
else
return true;
}
в моем классе dal
public void UserNameCheck(string alias)
{
string query6;
try
{
OpenCnn();
query6 = "Select count(*) from cntc_employee where emp_alias= '" alias "' ";
cmd = new SqlCommand(query6, con);
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
CloseCnn();
}
}
Комментарии:
1. в классе dll я думаю, что я должен вернуть объект возвращает ли функция bool объект (я так не думаю), что если cond exprn в классе bll
2. Я действительно не понимаю, чего вы хотите… пожалуйста, объясните, чего вы хотите достичь… то, что вы только что написали, не имело для меня особого смысла, извините.
3. я хочу проверить, существует ли пользователь или нет в базе данных, используя 3 уровня, можете ли вы переписать мой класс BLl
Ответ №1:
Давайте начнем с уровня доступа к данным. Хотя ваша логика кажется правильной, я утверждаю, как вы возвращаете объекты. На мой взгляд, вам лучше вернуть логическое значение, указывающее, существует пользователь или нет. Кроме того, используйте параметризованные запросы, потому что вы не хотите SQLInjection. Смотрите код:
// Note: I changed the name to a more meaningfull use
public static bool UserExists(string alias)
{
bool userExists = false;
try
{
// Note: where do you initialise cmd?
cmd.Parameters.AddWithValue("alias", alias);
cmd.CommandText = "Select count(*) from cntc_employee where emp_alias=@alias";
cmd.Connection = con;
OpenCnn();
int amountOfUsersWithAlias = (int)cmd.ExecuteScalar();
if(amountOfUsersWithAlias > 0)
userExists = true;
}
catch (Exception ex)
{
throw ex;
}
finally
{
CloseCnn();
}
return userExists;
}
Итак, теперь у вас есть логическое значение, указывающее, существует ли пользователь. Если возвращаемое значение равно true, пользователи существуют. Если значение равно false, пользователь не существует.
Теперь в вашем Businesslayer вы вызываете вышеупомянутый метод:
public bool UserNameCheck(string alias)
{
if (UserClass.UserExists(alias))
return true
else
return false;
}
Вы вызываете статический метод для правильного псевдонима. Опять же, возвращается true или false, в зависимости от того, существует ли пользователь. Затем вы используете этот метод в своем presentationlayer и показываете ошибку пользователю, если возвращается значение true.
Возможно, это не идеальная 3-уровневая архитектура, но она выполняет свою работу.
Комментарии:
1. что такое userclass в Bll
2. Я предполагаю, что ваш метод находится в классе… Я создал статический метод, чтобы вы могли вызвать его с помощью class . Пользователь существует. Вы также можете сделать его нестатическим и использовать класс MyClass = new Class(); Затем MyClass . userExists(псевдоним).
Ответ №2:
public String UserNameCheck(String alias)
{
String returnValue = String.Empty;
SqlCommand cmd = null;
SqlDataAdapter adapter = null;
DataTable dt = null;
try
{
OpenCnn();
cmd =new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "Select count(*) from cntc_employee where emp_alias=@alias";
cmd,Parameter.Clear();
cmd.Parameter.AddWithValue("@alias", alias);
dt = new DataTable();
adapter = new SqlDataAdapter(cmd);
adapter.Fill(dt);
if(dt.Rows.Count > 0)
returnValue = "userNameIsExist";
else
returnValue = "userIsNotFound";
}
catch (Exception ex)
{
throw ex;
}
finally
{
if(dt != null) { dt.Dispose(); dt = null; }
if(adapter != null) { adapter.Dispose(); adapter null; }
if(cmd != null) { cmd.Parameter.Clear(); cmd.Dispose(); cmd = null; }
CloseCnn();
}
return returnValue;
}
Ответ №3:
Это именно то, для чего вы должны использовать a stored procedure
. Рассмотрим следующий сценарий:
2 пользователя одновременно отправляют одно и то же имя пользователя. ваш код отправляется в базу данных, проверяет, существует ли имя пользователя, возвращает false для обоих, а затем вставляет одно и то же имя пользователя для обоих пользователей.
Вместо того, чтобы проверять, существует ли имя пользователя в одном запросе, и вставлять его в другой, вы можете использовать хранимую процедуру для выполнения обоих этих действий, гарантируя, что вы не будете пытаться добавить одно и то же имя пользователя дважды. Я бы также рекомендовал создать unique constraint
имя пользователя (возможно, индекс, возможно, даже первичный ключ, в зависимости от ваших потребностей) для имени пользователя для этой таблицы базы данных.
Попробуйте следующий sql:
CREATE PROCEDURE stp_InsertUser (
@RequestedUserName nvarchar(10),
@OutUserAlrearyExists bit OUTPUT
)
AS
SET @OutUserAlrearyExists = 1
IF NOT EXISTS(
SELECT 1
FROM TblUsers
WHERE Users_UserName = @RequestedUserName
) BEGIN
INSERT INTO TblUsers(Users_UserName) VALUES (@RequestedUserName)
SET @OutUserAlrearyExists = 0
END
GO
Затем в вашем коде все, что вам нужно сделать, это выполнить эту хранимую процедуру.
Это также дает еще одно преимущество — вместо того, чтобы обращаться к базе данных 2 раза, вы заходите только один раз.
Ответ №4:
попробуйте это (личное):
private int UserExistCheck(string alias)
{
string query6;
try
{
OpenCnn();
query6 = "Select count(*) from cntc_employee where emp_alias= '" alias "' ";
cmd = new SqlCommand(query6, con);
return cmd.ExecuteScalar(); //-- or ExecuteNonQuery()
}
catch (Exception ex)
{
throw ex;
}
finally
{
CloseCnn();
}
}
и это (общедоступно) :
public bool UserNameCheck(string alias)
{
if (UserExistCheck(alias) > 0)
{
throw new Exception("Alias Already exist");
}
else
{
return true;
}
}
надеюсь, вам поможет
Редактировать:
PersonDAL :
public class PersonDAL
{
string connStr = ConfigurationManager.ConnectionStrings["TutTestConn"].ToString();
public PersonDAL()
{
}
public int Insert(string firstName, string lastName, int age)
{
SqlConnection conn = new SqlConnection(connStr);
conn.Open();
SqlCommand dCmd = new SqlCommand("InsertData", conn);
dCmd.CommandType = CommandType.StoredProcedure;
try
{
dCmd.Parameters.AddWithValue("@firstName", firstName);
dCmd.Parameters.AddWithValue("@lastName", lastName);
dCmd.Parameters.AddWithValue("@age", age);
return dCmd.ExecuteNonQuery();//-- if combination of user name and
} // password are not unique throw exception
catch
{
throw;
}
finally
{
dCmd.Dispose();
conn.Close();
conn.Dispose();
}
}}
и PersonBAL:
public class PersonBAL
{
public PersonBAL()
{
}
public int Insert(string firstName, string lastName, int age)
{
PersonDAL pDAL = new PersonDAL();
try
{
return pDAL.Insert(firstName, lastName, age);
}
catch
{
throw;
}
finally
{
pDAL = null;
}
}
}
Комментарии:
1. извините, сэр, я использую 3 уровня, и в классе bll должны быть созданы возражения
2. Демонстрация SQL-инъекции без каких-либо комментариев не может считаться ответом. Рассмотрите возможность добавления некоторых комментариев, объясняющих ваш код и исправляющих часть SQL-инъекции.