c# - Fill generic list from SqlDataReader - c#

How can I add values that a SqlDataReader returns to a generic List? I have a method where I use SqlDataReader to get CategoryID from a Category table. I would like to add all the CategoryID a generic List.
This dose not work because it returns only one categoryID and that is the last one. I want to add all the categoryID to the list and then return them.
How do I do that?
SqlConnection connection = null;
SqlDataReader reader = null;
SqlCommand cmd = null;
try
{
connection = new SqlConnection(connectionString);
cmd = new SqlCommand("select CategoryID from Categories", connection );
connection.Open();
List<int> catID = new List<int>();
dr = cmd.ExecuteReader();
while (dr.Read())
{
catID.Add(Convert.ToInt32(dr["CategoryID"].ToString()));
}
}
finally
{
if (connection != null)
connection.Close();
}
return catID;

Try like this, it's better, safer, uses lazy loading, less code, working, ...:
public IEnumerable<int> GetIds()
{
using (var connection = new SqlConnection(connectionString))
using (var cmd = connection.CreateCommand())
{
connection.Open();
cmd.CommandText = "select CategoryID from Categories";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
yield return reader.GetInt32(reader.GetOrdinal("CategoryID"));
}
}
}
}
and then:
List<int> catIds = GetIds().ToList();

Your current code should work, assuming catID is really declared before the try block, otherwise this won't compile.

AS BrokenGlass explained this is the demonstration
SqlConnection connection = null;
SqlDataReader dr= null;
SqlCommand cmd = null;
List<int> catID = new List<int>();
try
{
connection = new SqlConnection(connectionString);
cmd = new SqlCommand("select CategoryID from Categories", connection );
connection.Open();
dr = cmd.ExecuteReader();
while (dr.Read())
{
catID.Add(Convert.ToInt32(dr["CategoryID"].ToString()));
}
}
finally
{
if (connection != null)
connection.Close();
}
return catID;
as well as you change the declaration
SqlDataReader reader = null;
to
SqlDataReader dr= null; // Because you are using dr in the code not reader

This should work but I suggest you to use using with your connections
SqlConnection connection = null;
SqlDataReader reader = null;
SqlCommand cmd = null;
List<int> catID = new List<int>();
try
{
connection = new SqlConnection(connectionString);
cmd = new SqlCommand("select CategoryID from Categories", connection );
connection.Open();
dr = cmd.ExecuteReader();
while (dr.Read())
{
catID.Add(Convert.ToInt32(dr["CategoryID"].ToString()));
}
}
finally
{
if (connection != null)
connection.Close();
}
return catID;

List<int> s = new List<int>();
conn.Open();
SqlCommand command2 = conn.CreateCommand();
command2.CommandText = ("select turn from Vehicle where Pagged='YES'");
command2.CommandType = CommandType.Text;
SqlDataReader reader4 = command2.ExecuteReader();
while (reader4.Read())
{
s.Add(Convert.ToInt32((reader4["turn"]).ToString()));
}
conn.Close();

Related

Return results from SQL query in a specific format [duplicate]

I'm trying to get data from a SQL Server database and return data (all data) based on a query as follows:
public async Task<List<PersonEntity>> GetDataAsync()
{
var allUsers = new List<PersonEntity>();
SqlConnection conn = new SqlConnection("");
conn.Open();
SqlCommand cmd = new SqlCommand("Select* from <TABLE> <WHERE>", conn);
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
var a = new PersonEntity {
LocationAreaCode = reader.GetString(0),
PersonStatusCode = reader.GetString(1),
PersonStatusDesc = reader.GetString(2)
};
allUsers.Add(a);
}
}
else
{
// no data found
}
reader.Close();
conn.Close();
return allUsers;
}
Is there a better way (in terms of performance) to read all data (values from all the columns) matching the query and return the data from this function?
You need to use ADO.net SqlDataAdapter Class
var ds = new DataSet();
using (SqlConnection connection = new SqlConnection(connectionString)) {
connection.Open();
var command = connection.CreateCommand();
command.CommandText = "Select * from <table-name> where location = 'US'";
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);
}

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

ps : i tried to close connexions and datareaders but it didn't work , also tried the previous solutions here but still got the error
i even separed the connexions and it didn't work as well
what i'm trying to do here is to read an id from a table from the sql server
and use that id to look for another data in another table
but it always give me the closing connexion or data problem
SqlConnection cnx = new SqlConnection("data source = . ; database = tnt ; integrated security = true ; MultipleActiveResultSets=true");
SqlConnection cnx2 = new SqlConnection("data source = . ; database = tnt ; integrated security = true ; MultipleActiveResultSets=true");
SqlCommand cmd = new SqlCommand("select matricule from inscription where numformation = #n",cnx);
cmd.Parameters.AddWithValue("#n", comboBox2.Text);
SqlDataReader dr = cmd.ExecuteReader();
List<string> hawhaw = new List<string>();
while (dr.Read())
{
hawhaw.Add(dr[0].ToString());
}
cmd.Dispose();
cnx2.Close();
cnx2.Open();
SqlCommand cmd2 = new SqlCommand("select * from person where matricule = #m", cnx2);
foreach (var item in hawhaw)
{
cmd2.Parameters.Clear();
cmd2.Parameters.AddWithValue("#m", item);
SqlDataReader dr2 = cmd2.ExecuteReader();
if (dr2.Read())
{
MessageBox.Show(dr2[0].ToString());
}
}
cmd2.Dispose();
cnx.Close();
most importantly, you can manage dispose and close operations. For this you should use using and will do this job on your behalf.
List<string> hawhaw = new List<string>();
using (SqlConnection connection = new SqlConnection("data source = . ; database = tnt ; integrated security = true ; MultipleActiveResultSets=true"))
{
connection.Open();
using (SqlCommand cmd = new SqlCommand("select matricule from inscription where numformation = #n", connection))
{
cmd.Parameters.AddWithValue("#n", comboBox2.Text);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
hawhaw.Add(dr[0].ToString());
}
}
}
using (var connection = new SqlConnection("data source = . ; database = tnt ; integrated security = true ; MultipleActiveResultSets=true"))
{
connection.Open();
foreach (var item in hawhaw)
{
using (var cmd2 = new SqlCommand("select * from person where matricule = #m", connection))
{
cmd2.Parameters.AddWithValue("#m", item);
var dr2 = cmd2.ExecuteReader();
if (dr2.Read())
{
MessageBox.Show(dr2[0].ToString());
}
}
}
}

How to check whether sql query returning a value or not?

I have a SQL query. Just i want to check query returning a values or not using c#. Can any one help on this to fix it. Thanks in advance.
Sqlcommand cmd = new Sqlcomman("select Name from Engdetails",con)
if (query != 0)
{
some coding..
}
else
{
coding...
}
SqlCommand cmd = new SqlCommand("select Name from Engdetails",con)
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
// The command returns Row(s)
}
else
{
// No Row has been returned.
}
There are a number of ways to work with sqlCommand; some examples:
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
reader.Read();
...
or
using (SqlCommand cmd = new SqlCommand(query, connection))
{
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
adapter.Fill(data);
}
if it has data, the data will be in data.Tables
SqlCommand cmd = new SqlCommand("select Name from Engdetails", con);
int i = cmd.ExecuteNonQuery();
if (i > 0)
{
// somecoding
}
else
{
// somecoding
}
a example in this case rdr.GetString is Name value of the query.
using (MySqlConnection conn = new MySqlConnection(constr))
{
using (MySqlCommand cmd = new MySqlCommand())
{
MySqlDataReader rdr = null;
string[] dados_bd = new string[2];
conn.Open();
cmd.Connection = conn;
cmd.CommandText = sql;
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
if (estado == 1)
{
dados_bd[0] = rdr.GetString(0);
cmd.ExecuteNonQuery();
For the UPDATE, INSERT, and DELETE statements, the return value is the number of rows affected by the SQL statement.
For all other types of statements, the return value is -1.

Calling database using sql and using call in label in C#.

So i have code that can call a string from database that works perfectly for my label but when i try to call an integer it doesn't work. How can i reformat the code below to work for an integer?
string MoneySaved = null;
string sql = "Select Distinct(Tester) From VExecutionGlobalHistory Where Tester = 'strUserName'";
string connString = "myconnectionstringgoeshere";
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
using (SqlCommand command = new SqlCommand(sql, conn))
{
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
MoneySaved = reader[0] as string;
MoneySavedLabel.Text = MoneySaved;
//break for single row or you can continue if you have multiple rows...
break;
}
}
conn.Close();
}
Here is what worked:
string MoneySaved = null;
string sql = "Select Distinct(Tester) From VExecutionGlobalHistory Where Tester = 'strUserName'";
string connString = "myconnectionstringgoeshere";
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
using (SqlCommand command = new SqlCommand(sql, conn))
{
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
MoneySaved = reader[0].ToString();
MoneySavedLabel.Text = MoneySaved;
//break for single row or you can continue if you have multiple rows...
break;
}
}
conn.Close();
}

How to bind a datasource to a label control

It's easy to bind a data source to something like a gridview or repeater, but how would I do it with a label? Heres the sql connection that I want to modify. By the way, I don't need 2 way binding.
public void Sql_Connection(string queryString)
{
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["RBConnectionString"].ConnectionString);
SqlCommand cmd = new SqlCommand(queryString, conn);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
The query I'm using:
SELECT Description FROM RbSpecials WHERE Active=1
public string SqlConnection(string queryString)
{
using (var conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["RBConnectionString"].ConnectionString))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = queryString;
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// This will return the first result
// but there might be other
return reader.GetString(0);
}
}
return null;
}
}
This will also ensure that in case of exception all disposable objects are disposed and will properly return the SQLConnection to the connection pool in order to be reused.
And finally assign the Text property of the label:
lblTest.Text = SqlConnection("SELECT Description FROM RbSpecials WHERE Active=1");
use ExecuteReader rather than ExecuteNonQuery
public void Sql_Connection(string queryString)
{
using(SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings"RBConnectionString"].ConnectionString))
{
using(SqlCommand cmd = new SqlCommand(queryString, conn))
{
conn.Open();
using(SqlDataReader rdr = cmd.ExecuteReader())
{
while(rdr.Read())
{
lblDescription.Text = rdr.GetString(0);
}
}
}
}
}
using (SqlConnection con = new SqlConnection(Connection_String))
{
SqlCommand cmd = new SqlCommand("select * from Customers", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataReader adpt = cmd.ExecureReader();
if(rdr.Read())
{
lblName.Text = rdr[0].ToString();
}
}

Categories