I am getting data from SQL and putting it in list. here's what I am trying now,
public class Fruit //custom list
{
public string aID { get;set; } // can be more then 1
public string bID { get;set; } // only 2 but different aID
public string name { get;set; } // only 1 for selection of aID and bID
}
and this is how i am getting data from sql,
var Fruitee = new Fruit();
using (SqlConnection cn = new SqlConnection(CS()))
{
cn.Open();
SqlCommand sqlCommand= new SqlCommand("SELECT * FROM myTable", cn);
SqlDataReader reader = sqlCommand.ExecuteReader();
while (reader.Read())
{
Fruitee.add(reader["aID"], reader["bID"],reader["name"]) // ??? not sure what to put here as add is not available
}
cn.Close();
}
Table looks like this,
aID, bID, name
**
Problem
**
I am stuck how to add items to list and also is it best practice ?
List<Fruit> fruits = new List<Fruit>();
while (reader.Read())
{
Fruit f = new Fruit();
f.aID = (string) reader["aID"];
f.bID = (string) reader["bID"];
f.name = (string) reader["name"];
fruits.Add(f);
}
var list = new List<Fruit>();
while (reader.Read())
{
list.Add(new Fruit() { aID = reader["aID"].ToString(), bID = reader["bID"].ToString(), name = reader["name"].ToString() });
}
var Fruitee = new List<Fruit>();
while (reader.Read())
{
Fruitee.Add(new Fruit() { aID = reader["aID"].ToString(), bID = reader["bID"].ToString(), name = reader["name"].ToString() });
}
You need to actually read from the reader and that's what you're not doing. However, be aware of DBNulls.
So assuming that your custom list has an add function you could do something like the following.
while(reader.Read())
{
Fruitee.add(reader["aID"], reader["bID"], reader["name"]);
}
Related
Trying to output all of the contents of a column from a MSSQL database into an array and at the moment I am getting this as an output:
ConsoleApplication3.Program+ClassName
ConsoleApplication3.Program+ClassName
if I add an extra row to the column then there will be three of the same thing output. The code that is handling all of this is below.
public class ClassName
{
public string Col1 { get; set; }
}
static void Main(string[] args)
{
try
{
SqlConnection con = new SqlConnection("Data Source=;Network Library=DBMSSOCN; Initial Catalog = Backups; User ID = BackupsU; Password = ; ");
ClassName[] allRecords = null;
string sql = #"SELECT company_Name FROM Company";
using (var command = new SqlCommand(sql, con))
{
con.Open();
using (var reader = command.ExecuteReader())
{
var list = new List<ClassName>();
while (reader.Read())
list.Add(new ClassName { Col1 = reader.GetString(0) });
allRecords = list.ToArray();
}
foreach (var item in allRecords)
{
Console.WriteLine(item.ToString());
}
Console.ReadKey();
Console.WriteLine();
}
You need to reference the Col1 property on each instance of your ClassName class
foreach (var item in allRecords)
{
Console.WriteLine(item.Col1);
}
Without that, you are just calling Object.ToString() which unless overridden, will just return the full name of your class.
You need to either override ClassName.ToString() to return ClassName.Col1, or just use item.Col1 in your Console.Writeline statement.
Since .ToString is not overriden it falls back to Object.ToString(), which outputs the class name.
I'm creating a list <object> and here I'm adding my data from a database.
But I totally don't know how to deal with a list <object>.
public class ClassList
{
public int Name { get; set; }
public string Birthday { get; set; }
}
private void GetClassList()
{
SqlConnection conn = new SqlConnection(GlobalVar.ConnString);
SqlCommand cmd = new SqlCommand
("SELECT * " +
"FROM Class_Data ", conn);
conn.Open();
SqlDataReader dr = cmd.ExecuteReader();
try
{
List<ClassList> ClassList = new List<ClassList>();
while (dr.Read())
{
ClassList.Add(new ClassList()
{
Name = ___?___, //what should i write here
Birthday = ___?___ //and here
});
}
}
catch{}
finally
{
dr.Close();
conn.Close();
}
}
Having been looking for lots of information but still fail to work it out.
I will be very appreciated if someone could help!
This should do it:
List<ClassList> ClassList = new List<ClassList>();
while (dr.Read())
{
ClassList.Add(new ClassList()
{
Name = (int)dr["Name"], //the name of the db column
Birthday = dr["Birthday"].ToString();
});
}
As a side note, it maybe worth altering your query from SELECT *... to just selecting the columns you require, from readability/maintenance point of view.
Also, is Name really an int seems like it could be a string.
You can also refer to the documentation:
SqlDataReader.Item Property (String)
You can use column name that are return by your database query with dr like dr["ColumnName"]
ClassList.Add(new ClassList()
{
Name = dr["NameColum"], //what should i write here
Birthday = dr["BrithColum"] //and here
});
Something like that:
// You don't use "this" in the context
// It seems, that you want to return the collected data (List<ClassList>)
private static List<ClassList> GetClassList() {
// Put IDisposable into using
using (SqlConnection conn = new SqlConnection(GlobalVar.ConnString)) {
conn.Connect();
// You want to fetch two fields only, right? Not the entire table (*)
String sql =
#"select Name,
BirthDay
from Class_Data"
using (SqlCommand cmd = new SqlCommand(sql, conn)) {
List<ClassList> result = new List<ClassList>();
using (SqlDataReader dr = cmd.ExecuteReader()) {
while (dr.Read()) {
result.Add(new ClassList() {
Name = Convert.ToString(dr[0]),
Birthday = Convert.ToDateTime(dr[1])
});
}
}
return result;
}
}
}
You can access the column values with dr["ColumnName"].
I have one array list:
public ArrayList GetExpenseTypes()
{
ArrayList expArry = new ArrayList();
using (SqlConnection conn = new SqlConnection(connStr))
{
string sql = "SELECT ID, TITLE";
sql += " FROM EXPENSE_TYPE";
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataReader reader;
try
{
conn.Open();
reader = cmd.ExecuteReader();
while (reader.Read())
{
expArry.Add(new ListItem(reader["TITLE"].ToString(), reader["ID"].ToString()));
}
reader.Close();
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}
}
return expArry;
}
My ArrayList like this
1 name1
2 name2
3 name3
4 name4
5 name6
if my value is 4 i need to display name4
How i achieve that?
Instead of ArrayList you might want to use Dictionary<string,string> like this.
public IDictionary<string,string> GetExpenseTypes()
{
Dictionary<string,string> expArry = new Dictionary<string,string>();
// Your sql code
while (reader.Read())
{
expArry.Add(reader["TITLE"].ToString(), reader["ID"].ToString());
}
// The rest of your code
}
Then you can get the value like this
var values = GetExpenseTypes();
string valueYouWant = values["4"];
If on the other hand your problem is that when you use the ListItems in a web control you are seeing the wrong values, then you need to swap the parameters when you create the ListItem because the first parameter is the text that is displayed and the second is the value. Like this.
expArry.Add(new ListItem(reader["ID"].ToString(), reader["TITLE"].ToString()));
In which case you should consider using a List<ListItem> instead of ArrayList
you could use BinarySearch method if you are searching for value types; in your case this does not seem possible.
I think you may need to use a loop assuming that you can not use Linq (because of the framework employed);
int index = -1;
for(int i=0; i<expArray.Count;i++)
{
ListItem temp = (expArray[i] as ListItem);
if(temp != null && temp.Value == "some value")
{
index = i;
break;
}
}
I'd recommend first changing ArrayList to List<ListItem>. If you can't do that for some reason you could use (assuming each item is unique):
var x = expArry.Cast<ListItem>().SingleOrDefault(exp => exp.Value == value);
if (x != null)
//item was found
If you know the item will always be there just use Single if it will only be there once.
Don't use ArrayList, do something like this using a generic dictionary
public IDictionary<int, string> GetExpenseTypes()
{
var result = new Dictionary<int, string>();
using (var conn = new SqlConnection(connStr))
{
var getExpenses = new SqlCommand(
"SELECT ID, TITLE FROM EXPENSE_TYPE",
conn);
conn.Open();
using (var reader = command.ExecureReader())
{
while (reader.Read())
{
result.Add(reader.GetInt32(0), reader.GetString(1));
}
}
}
return result;
}
Then you could look up your string like this
var type4 = GetExpenseTypes()[4];
alternatively, don't get the whole list to find one value.
public string GetExpenseType(int id)
{
using (var conn = new SqlConnection(connStr))
{
var getExpenseType = new SqlCommand(
"SELECT TITLE FROM EXPENSE_TYPE WHERE ID = #p0",
conn);
getExpenseType.Parameters.Add(id);
conn.Open();
return (string)getExpenseType.ExecuteScalar();
}
}
If, for some bad reason, you want to stick with your ArrayList returning function, you can find your item like this.
var expenseTypes = GetExpenseTypes().OfType<ListItem>().ToDictionary(
li => int.Parse(li.Text),
li => li.Value);
var type4 = expenseTypes[4];
or, if you want to do this once.
var type4 = GetExpenseTypes().OfType<ListItem>()
.Single(li => li.Text == "4").Value;
I am trying to read values form my database. But why am I getting only values with no column name?
this is my controller. that returns the values in JSON
SqlCommand cmd = con.CreateCommand();
cmd.CommandText = "SELECT DISTINCT State FROM MyDBtable";
con.Open();
List<string> StateList = new List<string>();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
StateList.Add(reader[0].ToString());
}
return Json(new
{
myTable = StateList
}, JsonRequestBehavior.AllowGet);
and this is my JSON
{"myTable":["VA","CA"]}
Where as, it's suppose to give me
{"myTable":[{"State":"VA"},{"State":"CA"}]}
Why is it not reading and printing State
String does not have property "State". Create anonymous type instead:
myTable = StateList.Select(s => new { State = s })
UPDATE: Easiest solution for multiple columns - create a DTO for that
public class MyItem // of course use more descriptive name
{
public string State { get; set; }
public string Capital { get; set; }
// etc
}
And fill it from reader:
List<MyItem> items = new List<MyItem>();
while (reader.Read())
{
MyItem item = new MyItem();
item.State = reader[0].ToString();
item.Capital = reader[1].ToString();
// etc
items.Add(item);
}
return Json(new { myTable = items }, JsonRequestBehavior.AllowGet);
One more sample (with Dapper, which you can find on NuGet). Add using Dapper; to your code. Use same DTO class, as above.
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
return Json(new {
myTable = connection.Query<MyItem>("SELECT * FROM MyDBtable").ToList()
}, JsonRequestBehavior.AllowGet);
}
Because you are selecting state. This will create a new object where the State property is assigned the state, such that you get what you want:
SqlCommand cmd = con.CreateCommand();
cmd.CommandText = "SELECT DISTINCT State FROM MyDBtable";
con.Open();
List<string> StateList = new List<string>();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
StateList.Add(reader[0].ToString());
}
return Json(new
{
myTable = StateList.Select(i => new { State = i })
}, JsonRequestBehavior.AllowGet);
For additional columns, see lazyberezovsky's answer who has changed StateList to solve this.
Suppose I have this code (pseudocode)
class SomeClass
{
class Person
{
public static string Name { get; set; }
public static int Age { get; set; }
}
List<Person> person = new List<person>;
public void SelectPerson()
{
DataTable dt = new DataTable();
SqlConnection conn = GetConnection();
conn.Open();
SqlDataAdapter da = new SqlDataAdapter("SELECT name, age FROM person", conn);
da.Fill(dt);
}
}
Can I fill the List (person) based on the result of my DataAdapter?
How should I do it? Or is there any workaround? Thanks...
Probably the best way is not to read into a datatable first:
var dr = new DataReader(....) // Fill in what is needed, can't remember offhand
while(dr.Next())
{
persons.Add(
new Person() {
Name = (string) r["Name"],
Age = (int) r["Age"]
}
);
}
Caveat: You want to close the DataReader/connection quickly, don't do lots of processing. The above code is more efficient than using a DataTable as an intermediary.
But if you do want to use a data table first, you could use LINQ:
var list = dt.AsEnumerable().Select(r => new Person() {
Name = (string) r["Name"],
Age = (int) r["Age"] }
).ToList()
or just itterate of dt.Rows and create a new person and add it to the list
You should also use Using() statements around your connection and reader.
There's also Linq to DataSet that you could use to do something along these lines
var list = (from tr in dt.AsEnumerable()
select new Person() {
Name = tr.Field<string>("Name"),
Age = tr.Field<int>("Age")
}).ToList();
Robert beat me to the answer, just using slightly different syntax.
In addition to the other options presented, you could defer the execution until needed with a yield:
public static IEnumerable<Person> GetPeople()
{
using( var conn = GetConnection() )
{
conn.Open();
string sql = "SELECT name, age FROM person";
var cmd = new SqlCommand( sql, conn );
using( SqlDataReader rdr = cmd.ExecuteReader() )
{
if( rdr == null )
{
throw new NullReferenceException( "No People Available." );
}
while( rdr.Read() )
{
var person = new Person();
person.Name = rdr["name"].ToString();
person.Age = Convert.ToInt32 ( rdr["age"] );
yield return person;
}
}
}
}
First, you'll want to make your Name and Age fields non-static (so each instance of the class will have their own values for these properties.
Then you could do something like this:
foreach(DataRow row in dt.Rows){
Person p = new Person(){
Name = Convert.ToString(row["name"]),
Age = Convert.ToInt32(row["age"])
}
person.Add(p);
}
Hope this helps!
Yes you can. Iterate through the items in dt.Rows and convert them manually to Person objects.
A user recently asked me a question on converting a DataTable to a List<> in .NET 2.0. Here’s the code to do so:
C#
// Assuming there is a DataTable called dt
List<DataRow> drlist = new List<DataRow>();
foreach (DataRow row in dt.Rows)
{
drlist.Add((DataRow)row);
}