2014-09-12 6 views
2

Я работаю на простой странице регистрации, где пользователь не может ввести одно и то же имя пользователя или адрес электронной почты, я сделал код, который запрещает пользователю вводить имя пользователя, и это сработало, но когда Я пытался запретить пользователю вводить то же имя пользователя или электронную почту, что он не работал.проверка имени пользователя или электронной почты пользователя уже существует

и мой вопрос: «Как добавить другое условие, когда пользователь не может ввести электронную почту, которая уже существует?»

Я пытался сделать это в этом коде, но did't работы:

protected void Button_Click(object sender, EventArgs e) 
{ 
    SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); 
    SqlCommand cmd1 = new SqlCommand("select 1 from Table where Name [email protected]", con); 
    SqlCommand cmd2 = new SqlCommand("select 1 from Table where [email protected]", con); 

    con.Open(); 
    cmd1.Parameters.AddWithValue("@UserName", Name_id.Text); 
    cmd2.Parameters.AddWithValue("@UserEmail", Email_id.Text); 

    using (var dr1 = cmd1.ExecuteReader()) 
    { 
    if (dr1.HasRows) 
    { 
     Label1.Text = "user name already exists"; 
    } 
    using (var dr2 = cmd2.ExecuteReader()) 
    { 
     if (dr2.HasRows) 
     { 
     Label1.Text = "email already exists"; 
     } 
     else 
     { 
     dr1.Close(); 
     dr2.Close(); 
     //add new users 
     con.Close(); 
     } 
    } 
    } 
} 

, но я получаю эту ошибку:

There is already an open DataReader associated with this Command which must be closed first.

+2

закрыть свой первый 'using' блок перед выполнением' cmd2', Вы также можете использовать 'ExecuteScalar' и получить первую строку первым вместо использования 'ExecuteReader' – Habib

+0

, но вставляя новый код пользователя, следует использовать оба из них с помощью –

+0

Нет инструкции INSERT * (SQL) * ?? , * anyway * выполнить отдельный оператор для INSERT – Habib

ответ

2

Как я уже сказал в своем комментарии, ваш дизайн плох!

Сначала у вас должен быть уровень доступа к данным. Это должно быть проект в больших решениях, но в вашем случае вы можете поместить его в новый каталог. В этом каталоге вы создаете класс SqlManager, вот код:

public class SqlManager 
{ 

    public static string ConnectionString 
    { 
     get 
     { 
      return ConfigurationManager.ConnectionStrings["DevConnString"].ConnectionString; 
     } 
    } 

    public static SqlConnection GetSqlConnection(SqlCommand cmd) 
    { 
     if (cmd.Connection == null) 
     { 
      SqlConnection conn = new SqlConnection(ConnectionString); 

      conn.Open(); 

      cmd.Connection = conn; 

      return conn; 
     } 

     return cmd.Connection; 
    } 

    public static int ExecuteNonQuery(SqlCommand cmd) 
    { 
     SqlConnection conn = GetSqlConnection(cmd); 

     try 
     { 
      return cmd.ExecuteNonQuery(); 
     } 
     catch 
     { 
      throw; 
     } 
     finally 
     { 
      conn.Close(); 
     } 
    } 

    public static object ExecuteScalar(SqlCommand cmd) 
    { 

     SqlConnection conn = GetSqlConnection(cmd); 

     try 
     { 
      return cmd.ExecuteScalar(); 
     } 
     catch 
     { 
      throw; 
     } 
     finally 
     { 
      conn.Close(); 
     } 
    } 

    public static DataSet GetDataSet(SqlCommand cmd) 
    { 
     return GetDataSet(cmd, "Table"); 
    } 

    public static DataSet GetDataSet(SqlCommand cmd, string defaultTable) 
    { 
     SqlConnection conn = GetSqlConnection(cmd); 

     try 
     { 
      DataSet resultDst = new DataSet(); 

      using (SqlDataAdapter adapter = new SqlDataAdapter(cmd)) 
      { 
       adapter.Fill(resultDst, defaultTable); 
      } 

      return resultDst; 
     } 
     catch 
     { 
      throw; 
     } 
     finally 
     { 
      conn.Close(); 
     } 
    } 


    public static DataRow GetDataRow(SqlCommand cmd) 
    { 
     return GetDataRow(cmd, "Table"); 
    } 

    public static DataRow GetDataRow(SqlCommand cmd, string defaultTable) 
    { 
     SqlConnection conn = GetSqlConnection(cmd); 

     try 
     { 
      DataSet resultDst = new DataSet(); 

      using (SqlDataAdapter adapter = new SqlDataAdapter(cmd)) 
      { 
       adapter.Fill(resultDst, defaultTable); 
      } 

      if (resultDst.Tables.Count > 0 && resultDst.Tables[0].Rows.Count > 0) 
      { 
       return resultDst.Tables[0].Rows[0]; 
      } 
      else 
      { 
       return null; 
      } 
     } 
     catch 
     { 
      throw; 
     } 
     finally 
     { 
      conn.Close(); 
     } 
    } 
} 

После этого у вас должен быть слой бизнес-объекта. В более крупном решении находится проект в вашем каталоге case. Если вы находитесь на странице TaxesEdit.aspx, вы должны добавить класс Tax.cs в BO (бизнес-объект).

Пример методов класса, для вашей первой кнопки:

public DataSet GetTaxesByUserName(string userName) 
{ 
    SqlCommand cmd = new SqlCommand(@" 

     select 1 from Table where Name [email protected]"); 

     cmd.Parameters.AddWithValue("@UserName", userName); 

     return DA.SqlManager.GetDataSet(cmd); 
} 

Вы получать все необходимые данные в наборах данных. После того, что вы делаете проверки, как taxesDst.Tables [0] .Rows.Count> 0 (или == 0)

Для вставки вы можете иметь метод, как это:

public virtual void Insert(params object[] colValues) 
    { 
     if (colValues == null || colValues.Length % 2 != 0) 
      throw new ArgumentException("Invalid column values passed in. Expects pairs (ColumnName, ColumnValue)."); 

     SqlCommand cmd = new SqlCommand("INSERT INTO " + TableName + " ({0}) VALUES ({1})"); 

     string insertCols = string.Empty; 
     string insertParams = string.Empty; 

     for (int i = 0; i < colValues.Length; i += 2) 
     { 
      string separator = ", "; 
      if (i == colValues.Length - 2) 
       separator = ""; 

      string param = "@P" + i; 

      insertCols += colValues[i] + separator; 
      insertParams += param + separator; 

      cmd.Parameters.AddWithValue(param, colValues[i + 1]); 
     } 

     cmd.CommandText = string.Format(cmd.CommandText, insertCols, insertParams); 

     DA.SqlManager.ExecuteNonQuery(cmd); 
    } 

Для этого вам необходимо иметь Свойство TableName в текущем классе BO.

В этом случае эти методы могут использоваться повсюду, и вам нужно только одну строку кода, чтобы вызвать их, и никаких проблем, подобных вашим, не произойдет.

0

Это может работать, хотя есть несколько вещей, Я бы сделал иначе ...

protected void Button_Click(object sender, EventArgs e) 
{ 
    bool inputIsValid = true; 
    var con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); 
    var userNameCmd = new SqlCommand("SELECT 1 FROM Table WHERE Name = @UserName", con); 
    var emailCmd = new SqlCommand("SELECT 1 FROM Table WHERE Email = @UserEmail", con); 

    con.Open(); 
    userNameCmd.Parameters.AddWithValue("@UserName", Name_id.Text); 
    emailCmd.Parameters.AddWithValue("@UserEmail", Email_id.Text); 

    using (var userNameReader = userNameCmd.ExecuteReader()) 
    { 
     if (userNameReader.HasRows) 
     { 
      inputIsValid = false; 
      Label1.Text = "User name already exists"; 
     } 
    } 
    using (var emailReader = emailCmd.ExecuteReader()) 
    { 
     if (emailReader.HasRows) 
     { 
      inputIsValid = false; 
      Label1.Text = "Email address already exists"; 
     } 
    } 

    if (inputIsValid) 
    { 
     // Insert code goes here 
    } 
    con.Close(); 
} 
+0

где я должен положить код вставки? –

+0

@Hbk Hhh - ну, это другой вопрос, чем тот, который вы задали, и ваш образец не содержал никакого кода вставки. Возможно, вы захотите отследить, были ли ошибки с использованием 'bool inputIsValid = true;' в верхней части метода. Затем установите его в '' false' внутри блока 'if (reader.HasRows)'. Наконец, перед тем, как закрыть соединение, вы можете иметь блок: 'if (inputIsValid) {}' –

+0

обновленный код с кодом вставки вставьте код –

0

Перед тем, как открыть другой, вам нужно закрыть один datareader. Несмотря на то, что это не так, как я бы это сделать, но вы можете иметь дело с ошибкой времени выполнения, закрыв DataReader после каждого IF:

using (var dr1 = cmd1.ExecuteReader()) 
{ 
    if (dr1.HasRows) 
    { 
     string Text = "user name already exists"; 
    } 
    dr1.Close(); 
} 

using (var dr2 = cmd2.ExecuteReader()) 
{ 
    if (dr2.HasRows) 
    { 
     string ext = "email already exists"; 
    } 

    else 
    { 
     //add new users 
    } 
    dr2.Close(); 
} 
con.Close(); 
0

Вы открыли еще DataReader внутри Первая и то вызывает проблему .. я переделали немного проверить это.

SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); 
     SqlCommand cmd1 = new SqlCommand("select 1 from Table where Name [email protected]", con), 
     cmd2 = new SqlCommand("select 1 from Table where [email protected]", con); 

     con.Open(); 
     cmd1.Parameters.AddWithValue("@UserName", Name_id.Text); 
     cmd2.Parameters.AddWithValue("@UserEmail", Email_id.Text); 

     bool userExists = false, mailExists = false; 

     using (var dr1 = cmd1.ExecuteReader()) 
      if (userExists = dr1.HasRows) Label1.Text = "user name already exists"; 

     using (var dr2 = cmd2.ExecuteReader()) 
      if (mailExists = dr2.HasRows) Label1.Text = "email already exists"; 

     if (!(userExists || mailExists)) 
     { 
      //add User 
     } 
+0

, это также помогает. –

+0

Всегда приветствую, если вы нажмете upvote один раз, пожалуйста. – Sayka

+0

приятный лаконичный, хотя выполнение заданий в операторах условий может быть немного сложным для начинающих, чтобы отлаживать ... :) –

0

Почему бы вам не сделать что-то вроде этого:

[Flags] 
public enum ValidationStatus 
{ 
    Valid   = 0 , 
    UserNameInUse = 1 , 
    EmailInUse = 2 , 
} 
public ValidationStatus ValidateUser(string userName , string emailAddr) 
{ 
    ValidationStatus status ; 
    string connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString ; 

    using (SqlConnection con = new SqlConnection(connectionString)) 
    using (SqlCommand cmd = con.CreateCommand()) 
    { 
    cmd.CommandText + @" 
     select status = coalesce((select 1 from dbo.myTable t where t.UserName = @UserName ) , 0) 
        + coalesce((select 2 from dbo.myTable t where t.UserEmail = @UserEmail) , 0) 
     " ; 
      cmd.Parameters.AddWithValue("@UserName" , userName ) ; 
      cmd.Parameters.AddWithValue("@emailAddr" , emailAddr) ; 

    int value = (int) cmd.ExecuteScalar() ; 
    status = (ValidationStatus) value ; 

    } 

    return status ; 
} 

Помимо всего прочего, попав в БД дважды что-то вроде этого глупо. И это более четко выражает намерение.

Затем вы можете использовать его в кнопке обработчик щелчка, что-то вроде этого:

protected void Button_Click(object sender , EventArgs e) 
{ 
    string   userName = Name_id.Text ; 
    string   emailAddr = Email_id.Text ; 
    ValidationStatus status = ValidateUser(userName , emailAddr) ; 

    switch (status) 
    { 
    case ValidationStatus.Valid   : 
    Label1.Text = "" ; 
    break ; 
    case ValidationStatus.EmailInUse : 
    Label1.Text = "Email address in use" ; 
    break ; 
    case ValidationStatus.UserNameInUse : 
    Label1.Text = "User name in use" ; 
    break ; 
    case ValidationStatus.EmailInUse|ValidationStatus.UserNameInUse: 
    Label1.Text = "Both user name and email address in use." ; 
    break ; 
    default : 
    throw new InvalidOperationException() ; 
    } 

    if (status == ValidationStatus.Valid) 
    { 
    CreateNewUser() ; 
    } 
} 
Смежные вопросы