How to put a Access Table into a C# array? - c#

I have a MS-Access table in my database called "RichtingEnJaar".
This table has 2 columns: the "ID" and "Naam".
I need to get the whole column "Naam" to be in an array in C#.
I tried a lot already but can't seem to find the correct answer.
Can any of you help me out real quick?
connect.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=H:\Project Officieel\Project_MagnusCurriculum\Project_MagnusCurriculum\Project.accdb";
connect.Open();
OleDbCommand cmdKlassen = new OleDbCommand("SELECT Naam FROM RichtingEnJaar WHERE ID = 1", connect);
if (connect.State == ConnectionState.Open)
{
try
{
OleDbDataReader KlasReader = null;
KlasReader = cmdKlassen.ExecuteReader();
while (KlasReader.Read())
{
Klas[0].Naam = KlasReader["Naam"].ToString();
}
connect.Close();
}
catch (Exception expe)
{
MessageBox.Show(expe.Source);
connect.Close();
}
}
else
{
MessageBox.Show("Connection failed");
}
Tried a new one:
string connStringKlas = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=H:\Project Officieel\Project_MagnusCurriculum\Project_MagnusCurriculum\Project.accdb";
DataTable resultsKlas = new DataTable();
using (OleDbConnection connKlas = new OleDbConnection(connStringKlas))
{
OleDbCommand cmdKlas = new OleDbCommand("SELECT Naam FROM RichtingEnJaar", connKlas);
connKlas.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter(cmdKlas);
adapter.Fill(resultsKlas);
for (int i = 0; i <= resultsKlas.Rows.Count - 1; i++)
{
Klas[i].Naam = resultsKlas.Rows[i].ToString();
}
connKlas.Close();
}
MessageBox.Show(Klas[0].Naam.ToString());
Got an error on line Klas[i].Naam = resultsKlas.Rows[i].ToString(); saying 'System.NullReferenceException'.

It is not quite clear what Klas is, but supposing it is some array.
It looks like Klas[0].Naam = KlasReader["Naam"].ToString(); is problem source. You're putting all results from query into the same variable.
It should be some list or another collection you're adding your query results to, not a single Klas[0].Naam variable.
For example (skipping irrelevant parts of your code)
var list = new List<KlasStruct>();
while (KlasReader.Read())
{
var k = new KlasStruct();
k.Naam = KlasReader["Naam"].ToString()
list.Add(k);
}
And later (if you really need array, not list) you can transform list to array using List.ToArray() method.
Like this:
Klas = list.ToArray();

Since you may not know how many records there are in your database, you can use a list to fill from the database, and convert this list to an array:
var klasList = new List<KlasStruct>();
connect.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=H:\Project Officieel\Project_MagnusCurriculum\Project_MagnusCurriculum\Project.accdb";
connect.Open();
OleDbCommand cmdKlassen = new OleDbCommand("SELECT Naam FROM RichtingEnJaar WHERE ID = 1", connect);
if (connect.State == ConnectionState.Open)
{
try
{
OleDbDataReader KlasReader = null;
KlasReader = cmdKlassen.ExecuteReader();
while (KlasReader.Read())
{
klasList2.Add(new KlasStruct() { Naam = KlasReader["Naam"].ToString());
}
connect.Close();
Klas = klasList.ToArray();
}
catch (Exception expe)
{
MessageBox.Show(expe.Source);
connect.Close();
}
}
else
{
MessageBox.Show("Connection failed");
}

Related

Fastest way to join multiple data tables from multiple functions - c#

A function in my app is returning a data table by joining the data tables getting from many other sub functions. Each sub functions are independent to each other with common primary key. Now, It takes nearly two minutes to execute the function for 50 of students. Please suggest me a best/fastest way to achieve the same.
public DataTable ShowReportOnGridivew(int class_id, string searchDate)
{
DataTable dt_students_List = null;
try
{
//====Main Table=====//
dt_students_List = GetDistinctStudentList(class_id);//there will be around minimum of 50 students
if (dt_students_List != null)
dt_students_List.PrimaryKey = new DataColumn[] { dt_students_List.Columns["student_id"] };
//Tables need to merge with main table
DataTable dt_CurrentRank = null;
DataTable dt_ScoreInEnglish = null;
DataTable dt_AcademicDetails = null;
DataTable dt_ExtraCurriculam = null;
DataTable dt_Attendance = null;
DataTable dt_Arts = null;
DataTable dt_FuelToBridger = null;
DataTable dt_FuelToAircraft = null;
DataTable dt_TeacherFeedback = null;
DataTable dt_TotalScore = null;
foreach (DataRow row in dt_students_List.Rows)
{
string student_id = row["student_id"].ToString();//primary key
//==========Current Rank================//
dt_CurrentRank = GetCurrentRank(student_id);//Binding data using sql
dt_CurrentRank.PrimaryKey = new DataColumn[] { dt_CurrentRank.Columns["student_id"] };
if (dt_CurrentRank != null)
{
dt_students_List.Merge(dt_CurrentRank);
}
//====== Score in English =====
dt_ScoreInEnglish = GetScoreInEnglish(student_id, searchDate);
dt_ScoreInEnglish.PrimaryKey = new DataColumn[] { dt_ScoreInEnglish.Columns["student_id"] };
if (dt_ScoreInEnglish != null)
{
dt_students_List.Merge(dt_ScoreInEnglish);
}
//====== Academic Details =====
dt_AcademicDetails= GetAcademicDetails(student_id);
dt_AcademicDetails.PrimaryKey = new DataColumn[] { dt_AcademicDetails.Columns["student_id"] };
if (ddt_AcademicDetails != null)
{
dt_students_List.Merge(dt_AcademicDetails);
}
//=====Similarly calling other functions and merging the columns to dt_students_List ======
}
}
catch (Exception show_error)
{
string log_data = "Response: Error- " + show_error.ToString();
obj.DatalogFile("StudentsList", log_data);
throw show_error;
}
return dt_students_List;
}
====== Each sub functions are written like below.=============
private async DataTable GetCurrentRank(string student_id)
{
DataTable dt = null;
SqlConnection con = new SqlConnection(conn);
SqlCommand cmd = null;
SqlDataReader dr = null;
string sql = string.Empty;
sql = "SELECT student_id,current_rank FROM student_details WHERE " +
" student_id = #student_id ";
cmd = new SqlCommand(sql, con);
con.Open();
try
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#student_id", student_id);
dr = cmd.ExecuteReader();
dt = new DataTable("CurrentRank");
dt.Columns.AddRange(new DataColumn[2] { new DataColumn("student_id", typeof(int)),
new DataColumn("current_rank", typeof(float))});
if (dr.HasRows)
{
dt.Load(dr);
}
string log_data = "Web App Function: GetCurrentRank \n";
log_data += "Response: " + JsonConvert.SerializeObject(dt);
obj.DatalogFile("GetCurrentRank", log_data);
return dt;
}
catch (Exception show_error)
{
string log_data = "Response: Error- " + show_error.ToString();
obj.DatalogFile("GetCurrentRank", log_data);
throw show_error;
}
finally
{
cmd.Dispose();
con.Close();
con.Dispose();
}
}
You can write multiple select statement in single stored procedure;
and get output in DataSet.
You can get all your tables in a single request:
CREATE PROCEDURE Demo
**Parameters**
AS
-- Your all functions select statements
GO;
C#:
public DataSet GetDataSet(string ConnectionString, string SpName)
{
SqlConnection conn = new SqlConnection(ConnectionString);
SqlDataAdapter da = new SqlDataAdapter();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = SpName;
da.SelectCommand = cmd;
DataSet ds = new DataSet();
///conn.Open();
da.Fill(ds);
///conn.Close();
return ds;
}

Fetch all needed data from 2 different databases

[UPDATED]
I got a situation here where I need to fetch data from 2 different databases and then combine it into a model. I have an API method I made here that takes care of that but the moment I started working with a second database I got really confused on how I can retrieve more than one item. I'll explain. Here is the code to that method:
private List<FidelityModel> models;
public List<FidelityModel> getFidelityInfo2(string jobID) {
FidelityModel fidelityInfo;
SqlCommand command;
SqlConnection conn;
SqlDataReader reader;
string cjsJobName, ipwNumber, overnight, site;
int packageCount;
DateTime sla;
models = new List<FidelityModel>();
using (conn = new SqlConnection(#"server = [servername]; database = Dropoff; Integrated Security = true;")) {
conn.Open();
command = new SqlCommand("SELECT " +
"[Job Name], " +
"[Job ID], " +
"[Package Count], " +
"[Ship Method] " +
"FROM [cjs_data] " +
"WHERE [File Name] LIKE '%FDY%' AND [JOB ID] = #jobID", conn);
command.Parameters.Add("#jobID", SqlDbType.VarChar);
command.Parameters["#jobID"].Value = jobID;
//restructure to assign search results to string to later assign to model, as we will search again for SLA in a different database
using (reader = command.ExecuteReader()) {
if (reader.HasRows) {
while (reader.Read()) {
fidelityInfo = new FidelityModel();
fidelityInfo.cjsJobName = reader.GetString(0);
fidelityInfo.ipwNumber = reader.GetString(1);
fidelityInfo.packageCount = reader.GetInt32(2);
if (fidelityInfo.cjsJobName.Contains("OVN")) { fidelityInfo.overnight = "Yes"; } else {
fidelityInfo.overnight = (reader.GetString(3).Equals("Overnight")) ? "Yes" : "No";
}
//site = (cjsJobName.Contains("EDG")) ? "EDGEWOOD" : "Other Site"; //not always the case
fidelityInfo.site = "EDGEWOOD";
models.Add(fidelityInfo);
}
}
}
}
//How to incorporate this following block of code into the same model?
using (conn = new SqlConnection(#"server = [servername]; database = MustMail; Integrated Security = true;")) {
conn.Open();
command = new SqlCommand("SELECT [SLA] FROM [Job] WHERE [JobID] = #jobID", conn);
command.Parameters.Add("#jobID", SqlDbType.VarChar);
command.Parameters["#jobID"].Value = jobID;
using (reader = command.ExecuteReader()) {
if (reader.HasRows) {
while (reader.Read()) {
//fidelityInfo.sla = reader.GetDateTime(0);
}
}
}
}
return models;
}
As you can see right now I just have it working without fetching the SLA because I have no idea how to actually add the result I am fetching from the second database to the same model.
For each row in the DataReader create a new FidelityModel and add it to the list. Something like:
while (reader.Read())
{
var m = new FidelityModel()
{
cjsJobName = reader.GetString(0),
ipwNumber = reader.GetString(1),
packageCount = reader.GetInt32(2),
sla = DateTime.Now
};
if (m.cjsJobName.Contains("OVN"))
{
m.overnight = "Yes";
}
else
{
m.overnight = (reader.GetString(3).Equals("Overnight")) ? "Yes" : "No";
}
models.Add(m);
}

How to filter one dropdownlist based on another selection

I have the following code which populates the Topic dropdownlist and saves it to a cached table:
bookingData2 = new DataTable();
DataTable DTable_List = new DataTable();
string connString = #"";
string query2 = #"Select * from [DB].dbo.[top]";// columng #1 = Specialty and column #2 = Topic
using (SqlConnection conn = new SqlConnection(connString))
{
try
{
SqlCommand cmd = new SqlCommand(query2, conn);
SqlDataAdapter da = new SqlDataAdapter(query2, conn);
da.Fill(bookingData2);
HttpContext.Current.Cache["cachedtable2"] = bookingData2;
bookingData2.DefaultView.Sort = "Topic ASC";
Topic.DataSource = bookingData2.DefaultView.ToTable(true, "Topic"); // populate only with the Topic column
Topic.DataTextField = "Topic";
Topic.DataValueField = "Topic";
Topic.DataBind();
Topic.Items.Insert(0, new ListItem("All Topics", "All Topics"));
da.Dispose();
}
catch (Exception ex)
{
string error = ex.Message;
}
}
I have the following code which populates the Specialty dropdownlist and saves it to another cached table:
bookingData = new DataTable();
DataTable DTable_List = new DataTable();
string connString = #"";
string query = #"select * from [DB].dbo.[SP]";
using (SqlConnection conn = new SqlConnection(connString))
{
try
{
SqlCommand cmd = new SqlCommand(query, conn);
SqlDataAdapter da = new SqlDataAdapter(query, conn);
da.Fill(bookingData);
bookingData.DefaultView.Sort = "Specialty ASC";
Specialty.DataSource = bookingData.DefaultView.ToTable(true, "Specialty");
Specialty.DataTextField = "Specialty";
Specialty.DataValueField = "Specialty";
Specialty.DataBind();
Specialty.Items.Remove("All Specialties");
Specialty.Items.Insert(0, new ListItem("All Specialties", "All Specialties"));
da.Dispose();
}
catch (Exception ex)
{
string error = ex.Message;
}
}
How can I code the Specialty dropdownlist index change to do the following and save it to a cache table for quick access:
protected void Specialty_SelectedIndexChanged(object sender, EventArgs e)
{
//re-populate the Topic dropdownlist to display all the topics based on the following criteria:
--> Where the Specialty column is either "All Specialties" OR "{specialty selected index value}"
}
Save bookingData2 table in ViewState or Session (I won't recommend to use session though) if it's not too heavy. Otherwise, its better you cache it or query the database again to repopulate it.
Let's assume you save bookingData2 in ViewState as follows in Page_Load
ViewState["bookingData2"] = bookingData2; // This should be before the following line
Topic.DataSource = bookingData2.DefaultView.ToTable(true, "Topic");
Then in your SelectedIndexChanged event do something like this
protected void Specialty_SelectedIndexChanged(object sender, EventArgs e)
{
//re-populate the Topic dropdownlist to display all the topics based on the following criteria:
// Where the Specialty column is either "All Specialties" OR "{specialty selected index value}"
DataTable bookingData2 = (DataTable)ViewState["bookingData2"];
Topic.DataSource = bookingData2.Where(i => i.Specialty == "All Specialties" || i.Specialty == Specialty.SelectedValue).DefaultView.ToTable(true, "Topic"); // populate only with the Topic column
Topic.DataTextField = "Topic";
Topic.DataValueField = "Topic";
Topic.DataBind();
Topic.Items.Insert(0, new ListItem("All Topics", "All Topics"));
}
Update - With Cached object
Do following in Specialty_SelectedIndexChanged event instead of where we used ViewState before.
if (HttpRuntime.Current.Cache["cachedtable2"] != null)
{
DataTable bookingData2 = HttpRuntime.Current.Cache["cachedtable2"] as DataTable;
// Rest of the code
}
I haven't tried this code. Let me know if you find any issues.
This is what solved it for me:
protected void Topic_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
if (Topic.SelectedIndex == 0)
{
string query = #"Specialty LIKE '%%'";
DataTable cacheTable = HttpContext.Current.Cache["cachedtable"] as DataTable;
DataTable filteredData = cacheTable.Select(query).CopyToDataTable<DataRow>();
filteredData.DefaultView.Sort = "Specialty ASC";
Specialty.DataSource = filteredData.DefaultView.ToTable(true, "Specialty");
Specialty.DataTextField = "Specialty";
Specialty.DataValueField = "Specialty";
Specialty.DataBind();
}
else
{
string qpopulate = #"[Topic] = '" + Topic.SelectedItem.Value + "' or [Topic] = 'All Topics'"; //#"Select * from [DB].dbo.[table2] where [Specialty] = '" + Specialty.SelectedItem.Value + "' or [Specialty] = 'All Specialties'";
DataTable cTable = HttpContext.Current.Cache["cachedtable2"] as DataTable;
DataTable fData = cTable.Select(qpopulate).CopyToDataTable<DataRow>();
if (fData.Rows.Count > 0)
{
fData.DefaultView.Sort = "Specialty ASC";
Specialty.DataSource = fData.DefaultView.ToTable(true, "Specialty");
Specialty.DataTextField = "Specialty";
Specialty.DataValueField = "Specialty";
Specialty.DataBind();
}
Specialty.Items.Insert(0, new ListItem("All Specialties", "All Specialties"));
}
}
catch (Exception ce)
{
string error = ce.Message;
}
}

Why is my SQLCeCommand ExecuteReader failing?

With the following code I get a less-than-helpful err msg (all I can see of the err msg in the truncated title bar of the exception dialog is, "System.Data.SQLServer...")
string query = "SELECT * FROM EVERYTHING";
SqlCeCommand cmd = new SqlCeCommand(query);
SqlCeConnection conn = new SqlCeConnection(myConnStr);
conn.Open();
cmd.Connection = conn;
SqlCeDataReader myReader = cmd.ExecuteReader(CommandBehavior.CloseConnection); // <-- Blows up bigger than an Augustus Gloop pinata
UPDATE
I added this:
MessageBox.Show(string.Format("query is {0}", query));
...to do a sanity check on just what the query that was failing was, to the end that clumps of hair are now scattered all about my work area. I had this to feed the query:
string vendorId = txtVendor.ToString().Trim();
...instead of this:
string vendorId = txtVendor.Text.ToString().Trim();
...and thus the query was "SELECT BLA FROM BLA WHERE BLA = System.Windows.Forms.Label"
Now I'm at least to a "No data exists for the row/column" err msg.
I'm not sure if CF supports the CommandBehavior.CloseConnection option.
Can you write it this way?
string query = "SELECT * FROM EVERYTHING";
var table = new DataTable();
using (var cmd = new SqlCeCommand(query, new SqlCeConnection(myConnStr)); {
try {
cmd.Connection.Open();
table.Load(cmd.ExecuteReader());
} catch (SqlException err) {
Console.WriteLine(err.Message); // <= Put a Break Point here.
} finally {
cmd.Connection.Close();
}
}
object col1 = null;
string strCol2 = null;
if (0 < table.Rows.Count) {
col1 = table.Rows[0][0];
object obj = table.Rows[0][1];
if ((obj != null) && (obj != DBNull.Value)) {
strCol2 = obj.ToString();
}
}
EDIT: Added DataTable and read 2 items from Row[0].

C# data reader does not retrieve the data

I am trying to load data into a textbox by using a DataReader depend on the Drop down list selection. Didn't get error from this code, but the data is not loaded into textbox. please correct me.
public void text()
{
cn1.Open();
string s;
s = "select Request_Type from component where Material_Code='" + Mcodeddl.SelectedItem.Text + "' ";
SqlCommand cd1 = new SqlCommand(s, cn1);
SqlDataReader rd;
try
{
rd = cd1.ExecuteReader();
while (rd.Read())
{
TextBox4.Text = rd["Request_Type"].ToString().Trim();
}
rd.Close();
}
catch (Exception e)
{
Response.Write(e.Message);
}
finally
{
cd1.Dispose();
cn1.Close();
}
}
public void MC()
{
Mcodeddl.Items.Clear();
ListItem li1 = new ListItem();
li1.Text = "-Select-";
Mcodeddl.Items.Add(li1);
Mcodeddl.SelectedIndex = 0;
cn1.Open();
string s1;
s1 = "select Material_Code from component";
SqlCommand cd1 = new SqlCommand(s1, cn1);
SqlDataReader dr1;
try
{
dr1 = cd1.ExecuteReader();
while (dr1.Read())
{
ListItem ni1 = new ListItem();
ni1.Text = dr1["Material_Code"].ToString().Trim();
Mcodeddl.Items.Add(ni1);
}
dr1.Close();
}
catch (Exception e)
{
Response.Write(e.Message);
}
finally
{
cd1.Dispose();
cn1.Close();
}
}
If everything works fine without exceptions that is mean the connection established correctly and the SQL command is correct. I think you have to make sure about your SQL statement. Maybe it returns nothing because there are no matches.
We need more explain about your issue.

Categories

Resources