Following is the C# code for querying the DB to get the list of users id:
int id;
con = new SqlConnection(Properties.Settings.Default.ConnectionStr);
con.Open();
id = 180;
SqlCommand command = new SqlCommand("Select userid from UserProfile where grpid=#id", con);
command.Parameters.AddWithValue("#id", id);
using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.Read())
{
Console.WriteLine(String.Format("{0}", reader["userid"]));
}
}
con.Close();
Output: 5629
Actually, the list of Users having grpid = 180 are 5629, 5684, 5694.
How can I read the results in a list or an array ?
simply:
List<int> results = new List<int>();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
results.Add((int)reader["userid"]));
}
}
// use results
However, you might find a tool like "Dapper" a useful time saver here
var results = con.Query<int>("Select userid from UserProfile where grpid=#id",
new { id }).AsList();
Simply define a List, and use like:
List<string> Users = new List<string>();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Users.Add(reader[0].ToString());
}
}
Try this :
var userIds = new List<int>();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
userIds.Add(reader.GetInt32(0));
}
}
You could use this extension method:
public static class DbExtensions
{
public static List<T> ToList<T>(this IDataReader reader, int columnOrdinal = 0)
{
var list = new List<T>();
while(reader.Read())
list.Add((T)reader[columnOrdinal]);
return list;
}
}
Now you can use it in this way:
List<int> userIdList;
using (var con = new SqlConnection(Properties.Settings.Default.ConnectionStr))
{
using(var command = new SqlCommand("Select userid from UserProfile where grpid=#id", con))
{
command.Parameters.AddWithValue("#id", id);
con.Open();
using (SqlDataReader rd = command.ExecuteReader())
userIdList = rd.ToList<int>();
}
}
Related
I have the following code which establishing an SQL connection inside of a project I am working on. What I want to do is to create a for loop which contains a method and every time the loop repeats the method runs with a different value until all views of the returned query are used.
I can't figure out how to refer to every value of the view without saving the view to a list or an array first. Any ideas?
SqlConnection Con = new SqlConnection(#"Data Source=localhost\**;Initial Catalog=ML;User Id=sa;Password='**'");
string sql = #"select product_id,Name from E_PRODUCT_PROPERTY";
var mylist = new List<WineRating>();
using (var command = new SqlCommand(sql, Con))
{
Con.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
new WineRating { product_id = reader.GetInt32(0), Name = reader.GetString(1) };
///Here goes the code I suppose
method_name(reader.GetInt32(0), reader.GetString(1));
}
}
public static int method_name(int product_id, string Name)
{
int num = x *2;
Console.WriteLine(num + Name);
}
Perhaps like this:
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
MyMethodToPrintToScreen(reader.GetInt32(0), reader.GetString(1));
}
}
With the method to print to screen
private static void MyMethodToPrintToScreen(int id, string product)
{
//Do whatever you wish with the data: example
Console.WriteLine($"My id: {id} | Product: {product}");
}
Edit
Let me make it even more obvious(using your exact code):
SqlConnection Con = new SqlConnection(#"Data Source=localhost\**;Initial Catalog=ML;User Id=sa;Password='**'");
string sql = #"select product_id,Name from E_PRODUCT_PROPERTY";
var mylist = new List<WineRating>();
using (var command = new SqlCommand(sql, Con))
{
Con.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
method_name(reader.GetInt32(0), reader.GetString(1));
}
}
}
I am building a web API that connects to SQL and am trying to return all rows from the db in which the "StartDateTime" value is equal to today's date. For some reason, I am only getting one row instead of all rows that fit the definition. What do I need to change?
public class EventsController : ApiController
{
public List<tblEventDate> Get()
{
using (CalendarEntities entities = new CalendarEntities())
{
tblEventDate singleEvent = new tblEventDate();
List<tblEventDate> eventList = new List<tblEventDate>();
string strcon = ConfigurationManager.ConnectionStrings["DbConnCalendar"].ConnectionString;
SqlConnection con = new SqlConnection(strcon);
con.Open();
string comm = "SELECT [dbo].[tblEventDates].[EventID], [dbo].[tblEventDates].[StartDateTime], WHERE (CONVERT(date, dbo.tblEventDates.StartDateTime) = CONVERT(date, GETDATE()))";
SqlCommand cmd = new SqlCommand(comm, con);
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.HasRows)
{
while (reader.Read())
{
singleEvent.StartDateTime = (DateTime)(reader["StartDateTime"]);
singleEvent.EventID = (long)reader["EventID"];
eventList.Add(singleEvent);
}
reader.NextResult();
}
con.Close();
}
return eventList;
}
}
}
Try this:
conn.Open();
SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while (reader.Read())
{
if (reader.HasRows)
{
singleEvent.StartDateTime = (DateTime)(reader["StartDateTime"]);
singleEvent.EventID = (long)reader["EventID"];
eventList.Add(singleEvent);
}
}
I have put together the following method:
public static ArrayList DbQueryToArry()
{
string SqlCString = "connString";
SqlConnection connection = null;
ArrayList valuesList = new ArrayList();
connection = new SqlConnection(SqlCString);
connection.Open();
SqlCommand command = new SqlCommand("Select CLIENTNO, ACCOUNT_Purpose from audit.ACCOUNTS_AUDIT", connection);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
valuesList.Add(Convert.ToString(reader[0]));
}
return valuesList;
}
I'd like to be able to run an assertion like this one:
var a = DbQueryToArry();
Assert.IsTrue(a.Contains("some value"));
Given reader [0]
valuesList.Add(Convert.ToString(reader[0]));
I only get the first column (CLIENTINFO) into the array and not the second (ACCOUNT_Purpose). How should I modify the code to get both ?
In addition, the returned values could be either a String or Int so would my current code version should be handling both ?
Thanks in advance.
If we switch from obsolete ArrayList to something like IEnumerable<T>:
public static IEnumerable<IDataRecord> DbQueryToArray(string sql) {
if (null == sql)
throw new ArgumentNullException(nameof(sql));
//TODO: do not hardcode connetcion string but read it (say, from Settings)
string SqlCString = "connString";
//DONE: Wrap IDisposable into using
using (SqlConnection connection = new SqlConnection(SqlCString)) {
connection.Open();
//DONE: Wrap IDisposable into using
using (SqlCommand command = new SqlCommand(sql, connection)) {
//DONE: Wrap IDisposable into using
using (SqlDataReader reader = command.ExecuteReader()) {
while (reader.Read()) {
yield return reader as IDataRecord;
}
}
}
}
}
then you can use Linq in order to query the result:
var a = DbQueryToArray("Select CLIENTNO, ACCOUNT_Purpose from audit.ACCOUNTS_AUDIT");
Assert.IsTrue(a.Any(record =>
Convert.ToString(record["CLIENTNO"]) == "some value"));
Assert.IsTrue(a.Any(record =>
Convert.ToString(record["ACCOUNT_Purpose"]) == "some other value"));
If you don't want execute query several times, you can materialize the results:
var a = DbQueryToArray("Select CLIENTNO, ACCOUNT_Purpose from audit.ACCOUNTS_AUDIT")
.ToList();
Assert.IsTrue(a.Any(record => Convert.ToString(record[0]) == "some value"));
Assert.IsTrue(a.Any(record => Convert.ToString(record[1]) == "some other value"));
Finally (see comments below), if we want to test if any field in any record has the value:
var a = DbQueryToArray("Select CLIENTNO, ACCOUNT_Purpose from audit.ACCOUNTS_AUDIT")
.SelectMany(line => {
// Flatten the cursor into IEnumerable<String>
string[] result = new string[line.FieldCount];
for (int i = 0; i < result.Length; ++i)
result[i] = Convert.ToString(line[i]);
return result;
});
a.Any(item => item == "some value");
It is because you only read the first value of the reader. Reader.Read() read each row one by one and Convert.ToString(reader[0])) means that you want to read the first column as string.
That's cause you are getting only the first column. You can do something like below by specifying the column name
while (reader.Read())
{
valuesList.Add(Convert.ToString(reader["CLIENTNO"]));
valuesList.Add(Convert.ToString(reader["ACCOUNT_Purpose"]));
}
Moreover, since you are converting all the columns to string; I would suggest to use a strongly typed collection like List<string> rather then ArrayList valuesList = new ArrayList();
The other answers are good, However some concerns
Lets stop using ArrayList, and use a List<T> instead
Lets use a using statement where you can
Note : I have used a ValueTuple to return more than 1 field
Example
public static List<(string clientNo, string account)> DbQueryToArray()
{
const string SqlCString = "connString";
var valuesList = new List<(string clientNo, string account)>();
using (var connection = new SqlConnection(SqlCString))
{
connection.Open();
using (var command = new SqlCommand("Select CLIENTNO, ACCOUNT_Purpose from audit.ACCOUNTS_AUDIT", connection))
{
var reader = command.ExecuteReader();
while (reader.Read())
valuesList.Add(((string)reader[0],(string)reader[1]) );
}
}
return valuesList;
}
Usage
var results = DbQueryToArray();
Assert.IsTrue(results.Any(x => x.clientNo == someValue || x.account == someValue));
best practice is to check first if the reader has rows
reader.HasRows
then close the reader and the connection
your code should look like this:
public static ArrayList DbQueryToArry()
{
string SqlCString = "connString";
SqlConnection connection = null;
ArrayList valuesList = new ArrayList();
connection = new SqlConnection(SqlCString);
using (connection)
{
connection.Open();
SqlCommand command = new SqlCommand("Select CLIENTNO, ACCOUNT_Purpose from audit.ACCOUNTS_AUDIT", connection);
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
valuesList.Add(Convert.ToString(reader[0]));
valuesList.Add(Convert.ToString(reader[1])); // add to valuelist
}
}
reader.Close(); // close reader
} //dispose connection
return valuesList;
}
Use DataTable and SqlDataAdapter to get query result in form of table. Something like this:
string connString = #"your connection string here";
string query = "select * from table";
DataTable dataTable = new DataTable();
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand(query, conn);
conn.Open();
// create data adapter
SqlDataAdapter da = new SqlDataAdapter(cmd);
// this will query your database and return the result to your datatable
da.Fill(dataTable);
conn.Close();
da.Dispose();
Then you can use dataTable object to see if particular values exist.
I have a result of IEnumerable from a stored procedure and i am looping through the results inorder to get the value of a column(GUID). I am unsure of how to go about on getting the Guid column from my results set in the foreach loop
this is what i have:
var results = GetGuids(instId);
foreach (var item in results)
{
}
public IEnumerable GetGuids(int id)
{
using (SqlCommand _command = new SqlCommand("StoredProc"))
{
_command.Connection = new SqlConnection(conString);
_command.Connection.Open();
_command.CommandType = CommandType.StoredProcedure;
_command.Parameters.AddWithValue("#ItemID", id);
return _command.ExecuteReader();
}
}
You can't use most of the normal linq extension methods directly on the non-generic IEnumerable... but you can call .Cast<T>() to make it an IEnumerable<T>. At that point, things get easier:
public IEnumerable<Guid> GetGuids(int id)
{
using (SqlCommand _command = new SqlCommand("StoredProc"))
{
_command.Connection = new SqlConnection(conString);
_command.Connection.Open();
_command.CommandType = CommandType.StoredProcedure;
_command.Parameters.Add("#ItemID", SqlDbType.Int).Value = id;
return _command.ExecuteReader()
.Cast<DbDataRecord>()
.Select(r => (Guid)r["GuidColumn"]);
}
}
You need to produce the results yourself from the SqlDataReader
var results = GetGuids(instId);
foreach (var item in results)
{
}
public IEnumerable<Guid> GetGuids(int id)
{
using (SqlCommand _command = new SqlCommand("StoredProc"))
{
_command.Connection = new SqlConnection(conString);
_command.Connection.Open();
_command.CommandType = CommandType.StoredProcedure;
_command.Parameters.AddWithValue("#ItemID", id);
var guids = new List<Guid>();
using (SqlDataReader reader = _command.ExecuteReader())
{
while (reader.Read()
{
guids.Add( (Guid)reader["GuidColumn"]);
}
}
}
}
The list will grow and shrink depending on how many items I have in my database.
I need to populate a list not a listbox. I understand I will need to open a connection.
using (var conn = new SqlConnection(Properties.Settings.Default.DBConnectionString))
{
using (var cmd = conn.CreateCommand())
{
conn.Open();
List<string> TagList = new List<string>();
for (int i = 0; i < TagList.Count; i++)
TagList[i].Add("Data from database");
cmd.ExecuteNonQuery();
}
}
I'm really not sure how to do this and I'm sure my method up here looks very wrong so I really need help.
Could someone show me what I'm doing wrong?
public IEnumerable<string> GetTagList()
{
using (var connection = new SqlConnection(Properties.Settings.Default.DBConnectionString))
using (var cmd = connection.CreateCommand())
{
connection.Open();
cmd.CommandText = "select Tag from TagsTable"; // update select command accordingly
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
yield return reader.GetString(reader.GetOrdinal("Tag"));
}
}
}
}
then you can call it as below
List<string> tags = GetTagList().ToList();
I would like to share my solution, hope helps someone in the future:
public List<string> getFromDataBase()
{
List<string> result = new List<string>();
using(SqlConnection con = new SqlConnection("connectionString"))
{
con.Open();
DataTable tap = new DataTable();
new SqlDataAdapter(query, con).Fill(tap);
result = tap.Rows.OfType<DataRow>().Select(dr => dr.Field<string>("columnName")).ToList();
}
return result;
}
This would do as it is (if I didn't do any typos...)
private void LoadList()
{
List<string> tagsList = new List<string>();
using (IDbConnection connection = new SqlConnection(Properties.Settings.Default.DBConnectionString))
{
connection.Open();
using (IDbCommand command = connection.CreateCommand())
{
command.CommandText = "SELECT TAGCOLUMN FROM TAGSTABLE";
using (IDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
if (!reader.IsDBNull(0))
tagsList.Add(reader.GetString(0));
}
reader.Close();
}
}
connection.Close();
}
}
EDIT:
Of course you have to change the select statement to the correct one from your database.
I just used a pseudo one to show you what to put there.