Is it possible to use SQL command for login and update at the same time? I mean when the Login is done, I want to change logat in 1. Do I have to create a new if with OpenConnection()?
public bool IsLogin(string user, string pass) {
string query = $"SELECT * from utiliz WHERE username='{user}' AND password='{GetSha1(pass)}'";
string query_update = $"UPDATE utiliz SET logat='{1}' WHERE username='{user}'";
try
{
if (OpenConnection())
{
MySqlCommand cmd = new MySqlCommand(query, conn);
MySqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
reader.Close();
conn.Close();
return true;
}
else
{
reader.Close();
conn.Close();
return false;
}
}
else {
conn.Close();
return false;
}
}
catch (Exception ex) {
conn.Close();
return false;
}
}
EDITED
Guys, I have edited my code, following parameters procedure. Is it good what I did?
if (String.IsNullOrEmpty(textBox_pass_login.Text) && String.IsNullOrEmpty(textBox_usr_login.Text) || String.IsNullOrEmpty(textBox_usr_login.Text) || String.IsNullOrEmpty(textBox_pass_login.Text))
{
System.Windows.Forms.MessageBox.Show("Both fields (username,password) are required");
}
else
{
string user = textBox_usr_login.Text;
string password = textBox_pass_login.Text;
string encryptedpass = GetSha1(password);
try
{
using (var connection = conn)
{
string query = "SELECT * from utiliz WHERE username=#user AND password=#password";
using (var command = new MySqlCommand(query, conn))
{
command.Parameters.AddWithValue("#user", user);
command.Parameters.AddWithValue("#password", encryptedpass);
MySqlDataAdapter sda = new MySqlDataAdapter(command);
DataTable dt = new DataTable();
sda.Fill(dt);
conn.Open();
int i = command.ExecuteNonQuery();
conn.Close();
if (dt.Rows.Count > 0)
{
this.Hide();
var form2 = new Form1();
form2.Closed += (s, args) => this.Close();
form2.Show();
}
else
{
System.Windows.Forms.MessageBox.Show("Wrong credentials");
textBox_usr_login.Clear();
textBox_pass_login.Clear();
}
}
}
}
catch
{
System.Windows.Forms.MessageBox.Show("Wrong credentials");
textBox_usr_login.Clear();
textBox_pass_login.Clear();
}
}
There are some important points here. You must use Parameterized queries to improve the performence of your query on the database layer and avoid some problems such as sql injection. You also could use transactions to keep data integrity.
Check the sample bellow with comments (I didn't test this code, may not work properly on your environment):
public bool IsLogin(string user, string pass)
{
// prepare the queries with parameters with '#' and parameter name
const string query = "SELECT count(username) from utiliz WHERE username = #username AND password = #password";
const string query_update = "UPDATE utiliz SET logat = #logat WHERE username = #username";
// prepare the encrypted password
string encryptedPass = GetSha1(pass);
// use a result variable to use as the function result
bool result = false;
try
{
if (OpenConnection())
{
// start a transaction from the connection object
using (MySqlTransaction tran = conn.BeginTransaction())
{
try
{
int userFound = 0;
// prepare the MySqlCommand to use the query, connection and transaction.
using (MySqlCommand userCommand = new MySqlCommand(query, conn, tran))
{
userCommand.Parameters.AddWithValue("#username", user);
userCommand.Parameters.AddWithValue("#password", encryptedPass);
userFound = (int) userCommand.ExecuteScalar();
}
if (userFound > 0)
{
// prepare the MySqlCommand to use the query, connection and transaction to update data
using (MySqlCommand logatCommand = new MySqlCommand(query_update, conn, tran))
{
logatCommand.Parameters.AddWithValue("#logat", DateTime.Now);
logatCommand.Parameters.AddWithValue("#username", user);
logatCommand.ExecuteNonQuery();
}
}
// commit the transaction
tran.Commit();
result = true;
}
catch (Exception ex)
{
// perform some log with ex object.
tran.Rollback();
}
finally
{
conn.Close();
}
}
}
}
catch (Exception e)
{
// perform some log...
return false;
}
return result;
}
As recommended (and demonstrated) by Felipe Oriani, you should use parameterized queries.
Let me pinpoint, however, that you can do this with a single update query. The trick is to filter the update query on both user name and password:
UPDATE utiliz SET logat = #logat WHERE username = #username AND password = #password
You want to run the query with method ExecuteNonQuery, which returns the number of rows affected.
If credentials are valid, the where cause selects the relevant record and the update happens, returning 1 as the count of records affected. Else, no record is updated, and the method returns 0.
I need to find a record in C# but I get an InvalidOperationException:
public static Auto findAuto(int kfznr)
{
Auto retAuto = new Auto();
try
{
myOleDbConnection.Open();
string query = "SELECT * FROM Auto WHERE Auto.KFZNR = " + kfznr;
OleDbCommand select = new OleDbCommand();
select.Connection = myOleDbConnection;
select.CommandText = query;
OleDbDataReader reader = select.ExecuteReader();
while (reader.Read())
{
Auto at = new Auto(Convert.ToInt32(reader[0]), Convert.ToString(reader[1]), Convert.ToString(reader[2]));
retAuto = at;
}
}
catch (OleDbException e)
{
Console.WriteLine(e.ToString());
}
return retAuto;
}
I get the error in the while loop at the creation of the new Auto.
When I run the same query in the SQLDeveloper I get one record (take a look at the first screenshot) but in my C# program I get there is no data for my row/cell.
When I hover the reader I get the following image. It says that the reader has rows:
Hope that you can help me fix this problem.
You need to use reader.GetValue(0)
public static Auto findAuto(int kfznr)
{
Auto retAuto = new Auto();
try
{
myOleDbConnection.Open();
string query = "SELECT * FROM Auto WHERE Auto.KFZNR = " + kfznr;
OleDbCommand select = new OleDbCommand();
select.Connection = myOleDbConnection;
select.CommandText = query;
OleDbDataReader reader = select.ExecuteReader();
while (reader.Read())
{
Auto at = new Auto(Convert.ToInt32(reader.GetValue(0)), Convert.ToString(reader.GetValue(1)), Convert.ToString(reader.GetValue(2)));
retAuto = at;
}
}
catch (OleDbException e)
{
Console.WriteLine(e.ToString());
}
return retAuto;
}
Also wanted to add...you can access the reader values by column name as well using:
reader["ColumnName"]...don't forget the "" around the name of the column ;)
public static Auto findAuto(int kfznr)
{
Auto retAuto = new Auto();
try
{
myOleDbConnection.Open();
string query = "SELECT * FROM Auto WHERE Auto.KFZNR = " + kfznr;
OleDbCommand select = new OleDbCommand();
select.Connection = myOleDbConnection;
select.CommandText = query;
OleDbDataReader reader = select.ExecuteReader();
while (reader.Read())
{
Auto at = new Auto(Convert.ToInt32(reader["col1"]), Convert.ToString(reader["col2"]), Convert.ToString(reader["col3"]));
retAuto = at;
}
}
catch (OleDbException e)
{
Console.WriteLine(e.ToString());
}
return retAuto;
}
I have a problem with my SQL datareader, i want to make an external class and make the code in my xaml.cs as short as possible, because there are a lot of sqldatareaders needed in my program. for this I want to pass following two strings to the datareader class:
public void refreshcombobox()
{
cbGebruiker.Items.Clear();
database = new DataBase();
string sqlrdr = "(rdr.GetString(1).ToString().Trim())";
List<string> reader = database.ReaderRdr("Select * from Gebruikers", ref sqlrdr);
foreach (String str in reader)
{
cbGebruiker.Items.Add(str);
}
}
however, when I do this this is the result in my program instead of the actual results that are stored in the database:
http://i58.tinypic.com/301j2vo.jpg (I can't post images)
can somebody help me with this? I've searched everywhere...
I don't know how to pass the rdr.GetString(1).ToString().Trim() to make it actually look stuff up in the db. Instead of just copying the string directly into the list.
This is the class:
namespace ClassLib
{
public class DataBase
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["kassadatabase"].ConnectionString);
public object ScalarObject(string sql)
{
object value = null;
try
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
value = cmd.ExecuteScalar();
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
finally
{
if (conn != null) conn.Close();
}
return value;
}
public List<string> ReaderRdr(string sql)
{
SqlDataReader rdr = null;
List<string> reader = new List<string>();
try
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
//reader.Add(rdr.GetString(1).ToString().Trim());
}
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
finally
{
if (rdr != null) rdr.Close();
if (conn != null) conn.Close();
}
return reader;
}
//public List<string> ReaderRdr(string sql, ref string str)
//{
// SqlDataReader rdr = null;
// List<string> reader = new List<string>();
// try
// {
// conn.Open();
// SqlCommand cmd = new SqlCommand(sql, conn);
// rdr = cmd.ExecuteReader();
// while (rdr.Read())
// {
// //MessageBox.Show(str.ToString());
// //var strRdr = str;
// //MessageBox.Show(strRdr.ToString());
// //reader.Add(rdr.GetString(1).ToString().Trim());
// reader.Add(str);
// Console.WriteLine(String.Format("{0}", rdr[0]));
// }
// }
// catch (SqlException ex)
// {
// MessageBox.Show(ex.Message);
// }
// finally
// {
// if (rdr != null) rdr.Close();
// if (conn != null) conn.Close();
// }
// return reader;
//}
public void ExecuteNQuery(string insertString)
{
try
{
conn.Open();
SqlCommand cmd2 = new SqlCommand(insertString, conn);
cmd2.ExecuteNonQuery();
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
finally
{
if (conn != null) conn.Close();
}
}
}
}
public List<string> ReaderRdr(string sql)
{
SqlDataReader rdr = null;
List<string> reader = new List<string>();
try
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
//reader.Add(rdr.GetString(1).ToString().Trim());
}
.....
now in the methode public list i want to replace the //reader.Add(rdr.GetString(1).ToString().Trim()); part(wich works fine)
with a string that is passed to the method.
public List<string> ReaderRdr(string sql, string strRdr)
{
SqlDataReader rdr = null;
List<string> reader = new List<string>();
try
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
//reader.Add(strRdr);
}
I'm not 100% sure what you're trying to do, but I can tell you right now that this is what you're doing wrong - the string (str) you're passing to ReaderRdr is just a string literal of C# code. There's super hacky (super inadvisable) things you can do to mimic what exists in other languages as eval(), but there's no built-in way to do that in C#. Nothing (sensible) you do to "(rdr.GetString(1).ToString().Trim())" is ever going to get a string, or cast it to string, or trim anything.
Within your ReaderRdr function, all you're accomplishing is just to add the string str to your List<string> reader. This accomplishes nothing and has no bearing whatsoever on the results you get from your database query in your SqlDataReader rdr. If you want to store the data you actually get from your database, use rdr, not the (useless) string argument str.
Also, I feel like you must have left something out of your code - you're instantiating your SqlCommand cmd with conn as your second argument, but I don't see that defined anywhere within your ReaderRdr method, and it's not an argument passed to ReaderRdr. You don't have an SqlConnection object as a field or property within your class, do you?
As far as what you should maybe do, despite lacking much of any context in terms of your actual aims - if you want to get any given column of the result for each row returned by your SqlDataReader:
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
var yourDataCell = rdr[yourColumnIndex];
// or:
var yourDataCellOtherWay = rdr["YourColumnName"];
}
Alternately, you can just iterate through each of the cells in any given row produced by your SqlDataReader like so:
for(int i = 0 ; i < numberOfColumns; i++) {
// do something with rdr[i] here
}
I'm not sure if there's anything you can do establish numberOfColumns based on the state of your SqlDataReader, but others might know better.
You actually adding the String that you passed to a function to your reader reader.Add(str); You get the response from SQL I your rdr.
This item will show you something from your database:
Console.WriteLine(String.Format("{0}", rdr[0]));
I am trying to add Sql Parameters to my project but i have the database connections in a class. How would i go about adding them as the code is trying to read employerId as a column name
I have this code in a class to read and return from a database:
public SqlDataReader ExecuteQuery(String query)
{
SqlCommand cmd = new SqlCommand(query,sqlConn);
SqlDataReader reader = cmd.ExecuteReader();
return reader;
}
and this code in a web service:
[WebMethod]
public string CheckTime1(string employerId)
{
try
{
UseDatabase useDb = new UseDatabase("database.mdf");
string queryString = "SELECT * FROM [employer] WHERE [employerId] =" + employerId;
useDb.ConnectToDatabase();
SqlDataReader dbReader = useDb.ExecuteQuery(queryString);
if (dbReader != null && dbReader.HasRows)
{
return "RECORDS EXIST";
}
else if (dbReader == null)
{
return "RECORDS DONT EXIST";
}
else
{
return "Error";
}
useDb.DisconectDatabase();
}
catch (Exception exq)
{
return exq.ToString(); ;
}
}
Although I strongly encourage you to rethink your data access layer from scratch, here is an easy solution to your problem:
public SqlDataReader ExecuteQuery(String query, params object[] p)
{
SqlCommand cmd = new SqlCommand(query, sqlConn);
for (int i = 0; i < p.Length; i++)
{
cmd.Parameters.Add(new SqlParameter("#p"+i, p[i]));
}
SqlDataReader reader = cmd.ExecuteReader();
return reader;
}
Then call it like this:
public string CheckTime1(string employerId)
{
...
string queryString = "SELECT * FROM [employer] WHERE [employerId] = #p0";
SqlDataReader dbReader = useDb.ExecuteQuery(queryString, employerId);
...
}
I've got an ASP.NET webforms site using C# and .NET 4.0.
I've created a class for loading information from a SQL table into an object, which has been working fine for a while. Recently a couple of specific records crash the SqlDataReader I use to populate this class with a database timeout error. I can't find any reason for these records to crash the reader.
I've isolated the crash to the [Address] int type datafield that when excluded from the query, the reader works fine. I've checked the database and the values stored are not unusual, and changing them to 0, null, or other working data, still results in a timeout error. If I call the fields using ExecuteScalar(), the data populates properly without error.
What could be causing this behavior?
Here is the content of the error:
Server Error in '/' Application.
A transport-level error has occurred when receiving results from the
server. (provider: TCP Provider, error: 0 - The specified network name
is no longer available.)
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more
information about the error and where it originated in the code.
Exception Details: System.Data.SqlClient.SqlException: A transport-level error has occurred when receiving results from the
server. (provider: TCP Provider, error: 0 - The specified network name
is no longer available.)
Source Method
public void Populate(Guid UserId)
{
DAL db = new DAL();
using (SqlConnection con = db.GetConnection())
{
SqlCommand RowCount = new SqlCommand("SELECT COUNT([UserId]) FROM aspnet_Membership WHERE [UserId]=#UserId", con);
RowCount.Parameters.Add(new SqlParameter("#UserId", SqlDbType.UniqueIdentifier));
RowCount.Parameters["#UserId"].Value = UserId;
SqlDataReader rdr = null;
string sqlQuery = "SELECT [ApplicationId],[UserId],[Password],[PasswordFormat],[PasswordSalt],[MobilePIN],"+
"[Email],[LoweredEmail],[PasswordQuestion],[PasswordAnswer],[IsApproved],[IsLockedOut],[CreateDate],[LastLoginDate],[LastPasswordChangedDate],[LastLockOutDate]," +
"[FailedPasswordAttemptCount],[FailedPasswordAttemptWindowStart],[FailedPasswordAnswerAttemptCount],[FailedPasswordAnswerAttemptWindowStart],[Comment]," +
"[FirstName],[LastName],[Address] FROM aspnet_Membership WHERE [UserId]=#UserId";
SqlCommand sqlCommand = new SqlCommand(sqlQuery, con);
sqlCommand.Parameters.Add(new SqlParameter("#UserId", SqlDbType.UniqueIdentifier));
sqlCommand.Parameters["#UserId"].Value = UserId;
try
{
con.Open();
int Rows = (int)RowCount.ExecuteScalar();
if (Rows > 0)
{
rdr = sqlCommand.ExecuteReader();
while (rdr.Read())
{
this.ApplicationId = (Guid)rdr["ApplicationID"];
this.UserId = (Guid)rdr["UserId"];
this.Password = common.Coalesce(rdr["Password"], "");
this.PasswordFormat = common.Coalesce(rdr["PasswordFormat"], 0);
this.PasswordSalt = common.Coalesce(rdr["PasswordSalt"], "");
this.MobilePIN = common.Coalesce(rdr["MobilePIN"], "");
this.Email = common.Coalesce(rdr["Email"], "");
this.LoweredEmail = common.Coalesce(rdr["LoweredEmail"], "");
this.PasswordQuestion = common.Coalesce(rdr["PasswordQuestion"], "");
this.PasswordAnswer = common.Coalesce(rdr["PasswordAnswer"], "");
this.IsApproved = (bool)rdr["IsApproved"];
this.IsLockedOut = (bool)rdr["IsLockedOut"];
this.CreateDate = common.Coalesce(rdr["CreateDate"], DateTime.Now);
this.LastLoginDate = common.Coalesce(rdr["LastLoginDate"], DateTime.Now);
this.LastPasswordChangedDate = common.Coalesce(rdr["LastPasswordChangedDate"], DateTime.Now);
this.LastLockOutDate = common.Coalesce(rdr["LastLockOutDate"], DateTime.Now);
this.FailedPasswordAttemptCount = common.Coalesce(rdr["FailedPasswordAttemptCount"], 0);
this.FailedPasswordAttemptWindowStart = common.Coalesce(rdr["FailedPasswordAttemptWindowStart"], DateTime.Now);
this.FailedPasswordAnswerAttemptCount = common.Coalesce(rdr["FailedPasswordAnswerAttemptCount"], 0);
this.FailedPasswordAnswerAttemptWindowStart = common.Coalesce(rdr["FailedPasswordAnswerAttemptWindowStart"], DateTime.Now);
this.Comment = common.Coalesce(rdr["Comment"], "");
this.FirstName = common.Coalesce(rdr["FirstName"], "");
this.LastName = common.Coalesce(rdr["LastName"], "");
this.Address = common.Coalesce(rdr["Address"], 0);
}
rdr.Close();
}
con.Close();
}
catch (Exception ex) { if (con != null) { con.Close(); } throw ex; }
finally { if (con != null) { con.Close(); } }
}
}
Here's the modified method that doesn't error.
public void Populate(Guid UserId)
{
DAL db = new DAL();
using (SqlConnection con = db.GetConnection())
{
SqlCommand RowCount = new SqlCommand("SELECT COUNT([UserId]) FROM aspnet_Membership WHERE [UserId]=#UserId", con);
RowCount.Parameters.Add(new SqlParameter("#UserId", SqlDbType.UniqueIdentifier));
RowCount.Parameters["#UserId"].Value = UserId;
SqlDataReader rdr = null;
string sqlQuery = "SELECT [ApplicationId],[UserId],[Password],[PasswordFormat],[PasswordSalt],[MobilePIN],"+
"[Email],[LoweredEmail],[PasswordQuestion],[PasswordAnswer],[IsApproved],[IsLockedOut],[CreateDate],[LastLoginDate],[LastPasswordChangedDate],[LastLockOutDate]," +
"[FailedPasswordAttemptCount],[FailedPasswordAttemptWindowStart],[FailedPasswordAnswerAttemptCount],[FailedPasswordAnswerAttemptWindowStart],[Comment]," +
"[FirstName],[LastName] FROM aspnet_Membership WHERE [UserId]=#UserId";
SqlCommand sqlCommand = new SqlCommand(sqlQuery, con);
sqlCommand.Parameters.Add(new SqlParameter("#UserId", SqlDbType.UniqueIdentifier));
sqlCommand.Parameters["#UserId"].Value = UserId;
try
{
con.Open();
int Rows = (int)RowCount.ExecuteScalar();
if (Rows > 0)
{
rdr = sqlCommand.ExecuteReader();
while (rdr.Read())
{
this.ApplicationId = (Guid)rdr["ApplicationID"];
this.UserId = (Guid)rdr["UserId"];
this.Password = common.Coalesce(rdr["Password"], "");
this.PasswordFormat = common.Coalesce(rdr["PasswordFormat"], 0);
this.PasswordSalt = common.Coalesce(rdr["PasswordSalt"], "");
this.MobilePIN = common.Coalesce(rdr["MobilePIN"], "");
this.Email = common.Coalesce(rdr["Email"], "");
this.LoweredEmail = common.Coalesce(rdr["LoweredEmail"], "");
this.PasswordQuestion = common.Coalesce(rdr["PasswordQuestion"], "");
this.PasswordAnswer = common.Coalesce(rdr["PasswordAnswer"], "");
this.IsApproved = (bool)rdr["IsApproved"];
this.IsLockedOut = (bool)rdr["IsLockedOut"];
this.CreateDate = common.Coalesce(rdr["CreateDate"], DateTime.Now);
this.LastLoginDate = common.Coalesce(rdr["LastLoginDate"], DateTime.Now);
this.LastPasswordChangedDate = common.Coalesce(rdr["LastPasswordChangedDate"], DateTime.Now);
this.LastLockOutDate = common.Coalesce(rdr["LastLockOutDate"], DateTime.Now);
this.FailedPasswordAttemptCount = common.Coalesce(rdr["FailedPasswordAttemptCount"], 0);
this.FailedPasswordAttemptWindowStart = common.Coalesce(rdr["FailedPasswordAttemptWindowStart"], DateTime.Now);
this.FailedPasswordAnswerAttemptCount = common.Coalesce(rdr["FailedPasswordAnswerAttemptCount"], 0);
this.FailedPasswordAnswerAttemptWindowStart = common.Coalesce(rdr["FailedPasswordAnswerAttemptWindowStart"], DateTime.Now);
this.Comment = common.Coalesce(rdr["Comment"], "");
this.FirstName = common.Coalesce(rdr["FirstName"], "");
this.LastName = common.Coalesce(rdr["LastName"], "");
}
rdr.Close();
string sqlQuery2 = "SELECT [Address] FROM aspnet_Membership WHERE [UserId]=#UserId";
SqlCommand sqlCommand2 = new SqlCommand(sqlQuery2, con);
sqlCommand2.Parameters.Add(new SqlParameter("#UserId", SqlDbType.UniqueIdentifier));
sqlCommand2.Parameters["#UserId"].Value = UserId;
this.Address = common.Coalesce(sqlCommand2.ExecuteScalar(), 0);
}
con.Close();
}
catch (Exception ex) { if (con != null) { con.Close(); } throw ex; }
finally { if (con != null) { con.Close(); } }
}
}
You should show us more of your code than this, i assume that this is only a consequential error.
Normally opening already opened connections or closing already closed connections results in an Invalid Operation Exception and this is what you're doing here.
try{
con.Open();
//do something
con.Close(); //will be closed when no error was raised
}catch (Exception ex){
if (con != null){
// this will close if the error was raised in "do something"
con.Close();
}
throw ex; // you better thow the exception by throw (instead of throw ex) to keep the stacktrace
}finally {
if (con != null) {
// this will definitely cause an Invalid Operation Exception since the connection was already closed
con.Close();
}
}
You should instead use the using-statement to close and dispose the connection implicitely. If you want to close it manually, you should also check it's ConnectionState:
if (con != null && con.State != System.Data.ConnectionState.Closed){con.Close();}
An example which circumvents this with using-statement:
try{
using (var con = new System.Data.SqlClient.SqlConnection(conString)) {
using(var cmd = new System.Data.SqlClient.SqlCommand(command, con)){
con.open();
var reader = cmd.ExecuteReader();
while (reader.Read()) {
//do something
}
}
}//will automatically close connection
}
catch (Exception ex) {
//log exception and/or throw
throw;
}
I've modified your code a bit, cleaned it and added Using Statements. now the connections would close as they need to. BTW, you were trying to add a UserId parameter twice. Here's how it looks like now. a bit easier to read:
public void Populate(Guid UserId)
{
DAL db = new DAL();
using (SqlConnection con = db.GetConnection())
{
con.Open();
string sqlQuery = "SELECT [ApplicationId],[UserId],[Password],[PasswordFormat],[PasswordSalt],[MobilePIN]," +
"[Email],[LoweredEmail],[PasswordQuestion],[PasswordAnswer],[IsApproved],[IsLockedOut],[CreateDate],[LastLoginDate],[LastPasswordChangedDate],[LastLockOutDate]," +
"[FailedPasswordAttemptCount],[FailedPasswordAttemptWindowStart],[FailedPasswordAnswerAttemptCount],[FailedPasswordAnswerAttemptWindowStart],[Comment]," +
"[FirstName],[LastName],[Address] FROM aspnet_Membership WHERE [UserId]=#UserId";
using (SqlCommand sqlCommand = new SqlCommand(sqlQuery, con))
{
sqlCommand.Parameters.Add(new SqlParameter("#UserId", SqlDbType.UniqueIdentifier) { Value = UserId });
try
{
using (SqlDataReader rdr = sqlCommand.ExecuteReader())
{
if (rdr.HasRows)
{
while (rdr.Read())
{
this.ApplicationId = (Guid)rdr["ApplicationID"];
this.UserId = (Guid)rdr["UserId"];
this.Password = common.Coalesce(rdr["Password"], "");
this.PasswordFormat = common.Coalesce(rdr["PasswordFormat"], 0);
this.PasswordSalt = common.Coalesce(rdr["PasswordSalt"], "");
this.MobilePIN = common.Coalesce(rdr["MobilePIN"], "");
this.Email = common.Coalesce(rdr["Email"], "");
this.LoweredEmail = common.Coalesce(rdr["LoweredEmail"], "");
this.PasswordQuestion = common.Coalesce(rdr["PasswordQuestion"], "");
this.PasswordAnswer = common.Coalesce(rdr["PasswordAnswer"], "");
this.IsApproved = (bool)rdr["IsApproved"];
this.IsLockedOut = (bool)rdr["IsLockedOut"];
this.CreateDate = common.Coalesce(rdr["CreateDate"], DateTime.Now);
this.LastLoginDate = common.Coalesce(rdr["LastLoginDate"], DateTime.Now);
this.LastPasswordChangedDate = common.Coalesce(rdr["LastPasswordChangedDate"], DateTime.Now);
this.LastLockOutDate = common.Coalesce(rdr["LastLockOutDate"], DateTime.Now);
this.FailedPasswordAttemptCount = common.Coalesce(rdr["FailedPasswordAttemptCount"], 0);
this.FailedPasswordAttemptWindowStart = common.Coalesce(rdr["FailedPasswordAttemptWindowStart"], DateTime.Now);
this.FailedPasswordAnswerAttemptCount = common.Coalesce(rdr["FailedPasswordAnswerAttemptCount"], 0);
this.FailedPasswordAnswerAttemptWindowStart = common.Coalesce(rdr["FailedPasswordAnswerAttemptWindowStart"], DateTime.Now);
this.Comment = common.Coalesce(rdr["Comment"], "");
this.FirstName = common.Coalesce(rdr["FirstName"], "");
this.LastName = common.Coalesce(rdr["LastName"], "");
this.Address = common.Coalesce(rdr["Address"], 0);
}
}
}
}
catch
{
throw;
}
}
}
}
UPD: i've edited the code, to ignore the counting of rows, and modified the line common.Coalesce(rdr["Address"], 0);
I think you need to run SQL Profiler and attach it to your database to watch the queries come across and get the responses.
You might also execute your query directly in Management Studio.
I'm wondering if there isn't a covering index that the first query is pulling data from that is somehow corrupted.
Either way, the profiler ought to give you a few more hints.
Regarding the initial rowcount select. I don't understand your comment about it being there to protect against dbnulls and program crashes. If a record doesn't exist for that ID then when the call to while(reader.read()) { .. } isn't going to enter that branch, which is all your rowcount test is preventing.