Comparing dataSet values - c#

Im using this code to do display images to edit:
protected void Repeater_Outer_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item;
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
Repeater Inner = (Repeater)item.FindControl("image_Repeater");
HiddenField Inner_Id = (HiddenField)item.FindControl("HiddenField_Id");
MySqlConnection conn = new MySqlConnection(ConfigurationManager.ConnectionStrings["dbcnx"].ToString());
MySqlCommand cmdNew = new MySqlCommand();
cmdNew.Connection = conn;
cmdNew.Parameters.AddWithValue("#id", Inner_Id.Value);
cmdNew.CommandText = "SELECT * FROM images WHERE FK_album = #id";
conn.Open();
Inner.DataSource = cmdNew.ExecuteReader();
Inner.DataBind();
Label Label_Amount = (Label)item.FindControl("Label_Amount");
Label_Amount.Text = Convert.ToString(Inner.Items.Count);
conn.Close();
}
}
My problem is that each time the repeater runs it connects to the database which makes the page take really long to load (like 10 seconds)
So i want to populate a dataset or a generic List to databind instead. I've tried this:
protected static List<string> dataSetImages(){
MySqlConnection conn = new MySqlConnection(ConfigurationManager.ConnectionStrings["dbcnx"].ToString());
string sql = "select * from images";
MySqlCommand cmd = new MySqlCommand( sql, conn);
conn.Open();
MySqlDataAdapter sqlDataAdapter = new MySqlDataAdapter(cmd);
DataSet dataSet = new DataSet();
sqlDataAdapter.Fill(dataSet);
conn.Close();
List<string> imageList = new List<string>();
for (int i = 0; i <= dataSet.Tables[0].Rows.Count - 1; i++)
{
string id = dataSet.Tables[0].Rows[i].ItemArray[0].ToString();
string img_name = dataSet.Tables[0].Rows[i].ItemArray[1].ToString();
string img_alt = dataSet.Tables[0].Rows[i].ItemArray[2].ToString();
string FK_album = dataSet.Tables[0].Rows[i].ItemArray[3].ToString();
imageList.Add(id);
imageList.Add(img_name);
imageList.Add(img_alt);
imageList.Add(FK_album);
}
return imageList;
}
How can i use this and compare FK_album to Inner_Id.Value?

If you are insistent on using the RowFilter approach, then this is what you are looking for.
string expression = String.Format("FK_album = {0}", Inner_Id.Value);
DataRow[] filteredRows = imageList.Tables[0].Select(expression);
Here is an article on DataView RowFilter Syntax.

better if you can class like below
public class ImageDto
{
public string Id { get; set; }
public string Name { get; set; }
public string Alt { get; set; }
public string FK_album { get; set; }
}
then
protected static List<ImageDto> dataSetImages(){
List<ImageDto> imageList = new List<ImageDto>();
// add items
return imageList;
}
then you can call above method and get list of ImageDto
List<ImageDto> images = dataSetImages();
in your Repeater_Outer_ItemDataBound method you can do as below
Inner.DataSource = images.Where(i=>i.FK_album == Inner_Id.Value).ToList();

Related

How to retrieve data from DataTable by iterating through the rows

I want to put this into a loop, the code is working fine
but I can't make a loop for it.
When it detects a new data on a table it will automatically add
another item, on my code below it only shows two user controls but I need to generate all of the value in the table.
Here is the code
public partial class Form1 : Form
{
MySqlConnection connection = new MySqlConnection("datasource=localhost;port=3306;database=rmsdb;username=root;password=");
MySqlCommand command;
MySqlDataAdapter da;
public Form1()
{
InitializeComponent();
LRNincrement();
}
int poss = 10;
public void AddItems(string Text, bool Checked)
{
DynaItems item = new DynamicUserControl.DynaItems(Text, Checked);
PanelContainer.Controls.Add(item);
item.Top = poss;
poss = (item.Top + item.Height + 10);
}
private void additembtn_Click(object sender, EventArgs e)
{
LRNincrement();
txt.Text = "";
}
private void LRNincrement()
{
String selectQuery = "SELECT lrnnumber from rmsdb.studentstable";
command = new MySqlCommand(selectQuery, connection);
da = new MySqlDataAdapter(command);
DataTable table = new DataTable();
da.Fill(table);
if (table.Rows.Count > 0)
{
string trylol = table.Rows[0][0].ToString();
AddItems(trylol, true);
}
if (table.Rows.Count > 1)
{
string trylol1 = table.Rows[1][0].ToString();
AddItems(trylol1, true);
}
}
}
Replace the below the code
{
string trylol = table.Rows[0][0].ToString();
AddItems(trylol, true);
}
if (table.Rows.Count > 1)
{
string trylol1 = table.Rows[1][0].ToString();
AddItems(trylol1, true);
}
with
string itemName = string.Empty;
for(int i = 0; i< table.Rows.Count; i++)
{
itemName = table.Rows[i][0].ToString();
AddItems(itemName, true);
}
I am not able to test this code. But hope this help you to find the solution.

C# - Trying to add each value from a database into a list, but it is only adding the final value?

Here is my code:
private List<string> readFromDatabase()
{
SQLiteConnection m_dbConnection = new SQLiteConnection("Data Source=" + fileName + ".sqlite;Version=3;");
string sql = "SELECT * FROM formsData";
m_dbConnection.Open();
SQLiteDataReader dr = DatabaseHandler.ExecuteCommandReader(sql, m_dbConnection);
List<string> tempList = new List<string>();
if(dr.HasRows)
{
while (dr.Read())
{
tempList.Add(Convert.ToString(dr["fieldName"]));
tempList.Add(Convert.ToString(dr["dataType"]));
tempList.Add(Convert.ToString(dr["numberOfCharacters"]));
}
}
return tempList;
}
I am trying to make it add each value from the database into the list, however it is only adding the last value found, from the final column. Does anyone know how to solve this? Thank you...
you can use a DataTable instead of DataReader (even though its possible to achieve the same result with DataReader).
please check that discussion: Why is DataTable faster than DataReader.
also its a better practice to use Try-Catchsteatments when connecting to databases.
here is an example (based on your code) how to achieve that task usingDataTable:
private List<string> readFromDatabase()
{
DataTable dt = PullData();
List<string> tempList = new List<string>();
if (dt != null & dt.Rows.Count >0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
tempList.Add(Convert.ToString(dt.Rows[i]["fieldName"]));
tempList.Add(Convert.ToString(dt.Rows[i]["dataType"]));
tempList.Add(Convert.ToString(dt.Rows[i]["numberOfCharacters"]));
}
}
return tempList;
}
public DataTable PullData()
{
try
{
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();
return dataTable;
}
catch (Exception ex)
{
return null;
}
}
Make sure your record set is positioned at the first row before you start iterating through it.
Also, do you really want to take all the rows of the table and have them as sequential values in a list? Perhaps adding them to class might make more sense.
public class Record{
public string Name { get; set; }
public string Type { get; set; }
public int Size { get; set; }
}

Insert new row to SQL DB using Stored Procedure and two parameters

I am trying to insert a new row to SQL DB using a stored procedure that takes two parameters. I am using an asp.net gridview and checkboxes in the first column so that you can select the row. For each row that is selected, it will insert the new row which supplies the ProjectID. The CorpID is provided with the query string. I commented out some of the lines in my code because it is giving me errors and I am not sure how to do the rest. I am following a video on YouTube to get this done. In the video, they are deleting rows but I am attempting to insert rows. If anyone wants the link to the video it is this. Here is my code from the DataAccessLayer
public void AssociateCorpToProj(ProjectData pd)
{
using(SqlConnection cn = new SqlConnection(_dbConnection))
{
using(SqlCommand cm = new SqlCommand("InsertProjectEntity", cn))
{
cm.CommandType = CommandType.StoredProcedure;
cn.Open();
cm.Parameters.AddWithValue("#ProjectID", pd.ProjectID);
cm.Parameters.AddWithValue("#CorpID", pd.CorpID);
cm.ExecuteNonQuery();
cn.Close();
}
}
}
Here is my code for my code behind that calls the method from the DataAccessLayer
protected void btnAssociateProjects_Click(object sender, EventArgs e)
{
List < object > lstCorpProjAssoc = new List < object> ();
foreach(GridViewRow gvRow in gvProjects.Rows)
{
if (((CheckBox) gvRow.FindControl("cbInsert")).Checked)
{
string cID = ((Label) gvRow.FindControl("lblProjectID")).Text;
lstCorpProjAssoc.Add(cID);
}
}
foreach(ProjectData str in lstCorpProjAssoc)
{
DALSectionAccessData ap = new DALSectionAccessData(connString);
ProjectData pd = new ProjectData();
ap.AssociateCorpToProj(str);
}
}
In case anyone thinks they need the code for the stored procedure, here it is.
INSERT INTO [dbo].[ProjectEntity]
([ProjectID],[CorpID])
VALUES
(#ProjectID, #CorpID)
Also, the list class that I am using
public class ProjectData
{
public string CompanyName { get; set; }
public int ProjectID { get; set; }
public int CorpID { get; set; }
}
Let me know if you need more information to answer the question. Any help is much appreciated.
Try running this example and step through the code this will help you understand List<object> vs List<string> vs List<Class>
var listAllData = new List<object>();
for (var cnt = 0; cnt< 10; cnt++)
{
var lstProjectData = new List<object>() //you need to change yours to be new List<ProjectData>
{
string.Empty, //CompanyName
0, //ProjectID
0 //CorpId
};
lstProjectData [0] = string.Format("CompanyName {0}", cnt);
lstProjectData [1] = cnt+ 1;
lstProjectData [2] = cnt+ 2;
listAllData.Add(lstProjectData );
//from your List<ProjectData> you should be able to get at the variable
//as follows someVariable.CompanyName = ,
//someVariable.ProjectId = ,
//and someVariable = CorpId
}
For the code in the DataAccessLayer:
public void AssociateCorpToProj(int pd, int cd)
{
using(SqlConnection cn = new SqlConnection(_dbConnection))
{
using(SqlCommand cm = new SqlCommand("InsertProjectEntity", cn))
{
cm.CommandType = CommandType.StoredProcedure;
cn.Open();
cm.Parameters.AddWithValue("#ProjectID", pd);
cm.Parameters.AddWithValue("#CorpID", cd);
cm.ExecuteNonQuery();
cn.Close();
}
}
}
For the code for the code behind that calls the method from the DataAccessLayer:
protected void btnAssociateProjects_Click(object sender, EventArgs e)
{
List < int > lstCorpProjAssoc = new List < int > ();
foreach(GridViewRow gvRow in gvProjects.Rows)
{
if (((CheckBox) gvRow.FindControl("cbInsert")).Checked)
{
int cID = Convert.ToInt32(((Label) gvRow.FindControl("lblProjectID")).Text);
lstCorpProjAssoc.Add(cID);
}
}
foreach(int pstr in lstCorpProjAssoc)
{
DALSectionAccessData ap = new DALSectionAccessData(connString);
ap.AssociateCorpToProj(pstr, _cID);
}
}
Not using the list class. I tested this out and it worked. The parameters are both int so it worked perfectly.

c# winform display database data from combobox selection

I have a check button that will fetch the month and year in combo box:
private void cmdSend_Click(object sender, System.EventArgs e)
{
List<string>[] list;
list = dbConnect.Select(month_list.SelectedItem.ToString(), year_list.SelectedItem.ToString());
printer_info.Rows.Clear();
for (int i = 0; i < list[0].Count; i++)
{
int number = printer_info.Rows.Add();
printer_info.Rows[number].Cells[0].Value = list[0][i];
printer_info.Rows[number].Cells[1].Value = list[1][i];
printer_info.Rows[number].Cells[2].Value = list[2][i];
printer_info.Rows[number].Cells[3].Value = list[3][i];
}
}
The check button then pass the month and year to the select statement function:
public List<string>[] Select(string month,string year)
{
string query = "SELECT * FROM page_counter WHERE month = '#month' AND year = #year;";
//Create a list to store the result
List<string>[] list = new List<string>[4];
list[0] = new List<string>();
list[1] = new List<string>();
list[2] = new List<string>();
list[3] = new List<string>();
//Open connection
if (this.OpenConnection() == true)
{
//Create Command
MySqlCommand cmd = new MySqlCommand(query, connection);
cmd.Parameters.Add("#month",MySqlDbType.VarChar);
cmd.Parameters.Add("#year", MySqlDbType.Year);
cmd.Parameters["#month"].Value = month;
cmd.Parameters["#year"].Value = year;
//Create a data reader and Execute the command
MySqlDataReader dataReader = cmd.ExecuteReader();
//Read the data and store them in the list
while (dataReader.Read())
{
list[0].Add(dataReader["id"].ToString() + "");
list[1].Add(dataReader["month"].ToString() + "");
list[2].Add(dataReader["year"].ToString() + "");
list[3].Add(dataReader["page_count"].ToString() + "");
}
//close Data Reader
dataReader.Close();
//close Connection
this.CloseConnection();
//return list to be displayed
return list;
}
the data will then display on the gridview where all column are specified by default in page designer:
When I run the code, it doesnt have any error, but theres no value display on the gridview. Is there any mistake I make? Im newbie in c# winform,please advise.
I think you have two mistakes.First you should remove the single-quotes from query string:
string query = "SELECT * FROM page_counter WHERE month = #month AND year = #year;"
Because when you use single-quotes your parameter names treated as actual value.Secondly, I would highly recommend you to use a class for your item instead of a List<string>[].The class would look like this:
public class Data
{
public int Id { get; set; }
public string Month { get; set; }
public string Year { get; set; }
public int PageCount { get; set; }
}
Then create a List<Data> and populate it like this:
var dataList = new List<Data>();
while (dataReader.Read())
{
var item = new Data();
item.Id = Convert.Toınt32(dataReader["id"]);
item.Month = dataReader["month"].ToString();
item.Year = dataReader["year"].ToString();
item.PageCount = Convert.ToInt32(dataReader["page_count"]);
dataList.Add(item);
}
return dataList;
Then ofcourse change the returning type of your method:
public List<Data> Select(string month,string year)
Then all you need to do is set the DataSource property:
var list = dbConnect.Select(month_list.SelectedItem, year_list.SelectedItem);
printer_info.DataSource = list;

getting a select statement column info from combobox

Hopefully i don't sound confusing but i am not sure if what i am trying to get at is possible.
I have a select statement to get name, id, guid. I am setting the display to name and the value to Id for each combobox. Is there a way that i could also assign the guid to the combo box so that i could use it in my winforms app?
here is what i have for select statement:
private void secondChild_drp_SelectedIndexChanged(object sender, EventArgs e)
{
string secondChildId = secondChild_drp.SelectedValue.ToString();
using (SqlConnection con = new SqlConnection(conString))
{
con.Open();
using (SqlDataAdapter sda = new SqlDataAdapter("SELECT ... WHERE em.ChildID = (" + secondChildId + ")", conString))
{
DataTable dt = new DataTable();
sda.Fill(dt);
thirdChild_drp.ValueMember = "ID";
thirdChild_drp.DisplayMember = "DisplayName";
thirdChild_drp.DataSource = dt;
}
}
cmd.CommandText="StoreProcName";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#ChildID", secondChildId);
cmd.Connection = con2;
con2.Open();
reader = cmd.ExecuteReader();
var guid = reader.ToString();
reader.Close();
con2.Close();
}
right now when i run this it tells me reader = cmd.ExecuteReader(); has Procedure or function StoreProcName has too many arguments specified.
i just want to get the guid associated with the id i passed in.
You can get the guid from your datatable as follows where yourselectedid is the combobox selecteditem id.
var results = from row in dt.AsEnumerable()
where row.Field<int>("ID") == yourselectedid
select row;
now from results you can get all the desired columns you want
Basically the same answer as I already posted here:
You could define a simple object which you are filling from your data base query:
public class Item
{
public int ID { get; set; }
public string DisplayName { get; set; }
public Guid Guid{ get; set; }
}
Your implementation could look something like this (some mockup data):
listBox1.DataSource = items;
listBox1.DisplayMember = "DisplayName";
listBox1.ValueMember = "ID";
Then based on the value you selected, you can query through your items and get the item:
var key = (int)listBox1.SelectedValue;
foreach (var existingItem in items)
{
if (existingItem.Key == key)
{
//woohoo got it!
Debug.Print(existingItem.Guid.ToString())
}
}
you can put both of the value in the value member, separated by whichever character for separator like : "12;0000-000-0000" then separate again the Value Menber with a String.Split.

Categories