How can I add a column to a datatable and add data to each row based on a condition.
This is what I am trying to do
conn = new OleDbConnection(#"Provider=Microsoft.Jet.OleDb.4.0;
Data Source =" + Server.MapPath("App_Data\\LR Product Database 2000.mdb"));
conn.Open();
Dictionary<string, string> items = new Dictionary<string, string>();
OleDbCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT CODE, TITLE FROM tblProducts";
OleDbDataReader dbread = cmd.ExecuteReader();
while (dbread.Read())
{
productCode = (string)dbread["ProductCode"];
productTitle = items[productCode];
items.Add(productCode, productTitle);
}
sqlCon = new SqlConnection(ConfigurationManager.ConnectionStrings["LRVWebsite"].ToString());
sqlCon.Open();
dsSql = new DataSet();
SqlDataAdapter dba = new SqlDataAdapter(#"SELECT C.CustomerFirstName,C.CustomerLastName, C.CustomerCompany,C.CustomerPosition,C.CustomerCountry,C.CustomerProvince,C.CustomerContact,CP.ActionDate,CP.ProductCode,CP.CustomerEmail FROM tblCustomers C INNER JOIN tblCustomerProducts CP ON C.CustomerEmail = CP.CustomerEmail ORDER BY ActionDate DESC", connString);
dba.Fill(dsSql,"Products");
DataTable dt = dsSql.Tables["Products"];
foreach (DataRow dr in dt.Rows)
{
for (int i = 0; i < items.Count; i++)
{
if (dr["ProductCode"].ToString().Equals(productCode))
{
//here I want to add a new column and add data (productTitle) to the column
}
}
}
dba.Fill(dsSql,"Products");
DataTable dt = dsSql.Tables["Products"];
dt.Columns.Add("ColumnName", typeof(DataType));
if (dr["ProductCode"].ToString().Equals(productCode))
{
dr["ColumnName"] = value;
}
Further i would extend the code to avoid NullReferenceException
if (!String.IsNullOrEmpty(dr["ProductCode"]) && dr["ProductCode"].ToString().Equals(productCode))
{
dr["ColumnName"] = value;
}
http://msdn.microsoft.com/en-us/library/hfx3s9wd.aspx
Related
I have a checkedlistBox in C# that I am filling from sql-server.
I need to insert the checkeditems when creating a new record and I need to update the previous selected items of a certain record.
First I am trying to read the selected item of a specific record so i tried the following:
I compare the value member of every item with the list I am getting from the sql query if it matches I check the item.
So I need to use something like the value option.
if(checkedListBox1.Items.IndexOf(i).**Value**
string sql = #"select cs.id from[dbo].[Channel_availableSpecs] cas inner join[dbo].[Channel_specs] cs on cas.ChennelSpec_Id = cs.id
where cas.Channel_Id =" + val + "order by cs.id";
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dta = new DataTable();
da.Fill(dta);
foreach (DataRow dr in dta.Rows)
{
for (int i = 0; i < checkedListBox1.Items.Count; i++)
{
if(checkedListBox1.Items.IndexOf(i).**Value** == dr.ToString()) checkedListBox1.SetItemCheckState(i, CheckState.Checked);
}
conn.Close();
}
}
Fill Checkedlistbox
public static void FillCheckedListox(CheckedListBox checkedListBox, string query,string displayMember, string valueMember) {
using (SqlConnection con = new SqlConnection(ConnectionString))
{
using (SqlCommand cmd = new SqlCommand(query, con))
{
cmd.CommandType = CommandType.Text;
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
DataTable dt = new DataTable();
sda.Fill(dt);
((ListBox)checkedListBox).DataSource = dt;
((ListBox)checkedListBox).DisplayMember = displayMember;
((ListBox)checkedListBox).ValueMember = valueMember;
}
}
}
This is the solution
private void selectSpecs(DataTable table)
{
while (checkedListBox1.CheckedIndices.Count > 0)
{
checkedListBox1.SetItemChecked(checkedListBox1.CheckedIndices[0], false);
}
for (int i = 0; i < checkedListBox1.Items.Count; i++)
{
DataRow r;
r = ((DataRowView)this.checkedListBox1.Items[i]).Row;
string val = (r[this.checkedListBox1.ValueMember]).ToString();
channelsSpecs.Add(Convert.ToInt32(val));
r = null;
for (int j = 0; j < table.Rows.Count; j++)
foreach (DataRow dataRow in table.Rows)
foreach (var item in dataRow.ItemArray) if (val.ToString() == item.ToString()) checkedListBox1.SetItemChecked(i, true);
}
}
I have a database that contains a Column of 3 Defined Types and a Column of that contains numbers.
The types can appear severl time in the database.
I want to create a DataTable that will show each type one time only and sum up to numbers that relate to that type.
List<String> types = typesInTable(table);
DataTable t = new DataTable();
t.Clear();
t.Columns.Add("Type");
t.Columns.Add("Total Expenses");
foreach (String type in types)
{
DataRow tmp = t.NewRow();
tmp["Type"] = type;
int total = 0;
myConnection.Open();
OleDbDataReader reader = null;
OleDbCommand cmd = new OleDbCommand("SELECT [Type] , [Expense] FROM [" + table+"]", myConnection);
reader = cmd.ExecuteReader();
while (reader.Read())
{
if(reader["Type"].ToString().Equals(type))
{
total += Convert.ToInt32(reader["Expense"].ToString());
}
}
tmp["Total Expenses"] = total;
if (!t.Rows.Contains(tmp))
{
t.Rows.Add(tmp);
}
myConnection.Close();
}
This Code makes the types appear several times.
You can use this code to create DataTable that contains every type grouped with the sum :
DataTable t = new DataTable();
myConnection.Open();
string query = string.Format("SELECT Type, Sum(Expense) AS TotalExpenses FROM [{0}] group by Type", table);
OleDbCommand cmd = new OleDbCommand(query, myConnection);
OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
adapter.Fill(t);
myConnection.Close();
if You want to sum up the types from different tables all together in 1 DataTable use this:
List<String> tableList = serviceMethod.getTableList();
DataTable dtAllType = new DataTable();
foreach (string table in tableList)
{
DataTable dtTemp = new DataTable();
myConnection.Open();
string query = string.Format("SELECT Type, Sum(Expense) AS TotalExpenses FROM [{0}] group by Type", table);
OleDbCommand cmd = new OleDbCommand(query, myConnection);
OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
adapter.Fill(dtTemp);
for (int i = 0; i < dtTemp.Rows.Count; i++)
{
bool isDupe = false;
for (int j = 0; j < dtAllType.Rows.Count; j++)
{
if (dtTemp.Rows[i][0].ToString() == dtAllType.Rows[j][0].ToString())
{
dtAllType.Rows[j][1] = int.Parse(dtAllType.Rows[j][1].ToString()) + int.Parse(dtTemp.Rows[i][1].ToString());
isDupe = true;
break;
}
}
if (!isDupe)
{
dtAllType.ImportRow(dtTemp.Rows[i]);
}
}
myConnection.Close();
}
the dtAllType DataTable contain Type grouped with sum of Expence
DataTable dt = db.getProductIdFromCategoriesId(categories_id);
foreach (DataRow row in dt.Rows)
{
string products_id = row["products_id"].ToString();
DataTable dt5 = db.FillDataGridfromTree(int.Parse(products_id));
show_products.ItemsSource = dt5.DefaultView;
}
this code show one by one rows in datagridview
but i want to show all the product rows having categories_id in datagridview in one go
this is the function FillDataGridfromTree in databasecore class and its object is db
public DataTable FillDataGridfromTree(int product_Id)
{
string CmdString = string.Empty;
using (SqlCeConnection con = new SqlCeConnection(ConString))
{
CmdString = "SELECT products.product_id as ID, products.remote_products_id as Remote_ID, products_description.products_name as name,products.products_model as model,products.manufacturers_id as manufacturersId,products.products_image as Image,products.products_price as Price,products.products_weight as Weight,products.products_date_added as dateAdded,products.products_last_modified as lastModified,products.products_date_available as dateAvailable,products.products_status as status,products.products_tax_class_id as taxClass FROM products INNER JOIN products_description ON products.product_id=products_description.products_id where products_description.language_id=1 and products_description.products_id=" + product_Id;
SqlCeCommand cmd = new SqlCeCommand(CmdString, con);
SqlCeDataAdapter adapter = new SqlCeDataAdapter(cmd);
DataTable dt = new DataTable("products");
adapter.Fill(dt);
//show_products.ItemsSource = dt.DefaultView;
return dt;
}
}
this is the function through which i get product_id
public DataTable getProductIdFromCategoriesId(int categories_id)
{
string CmdString = string.Empty;
using (SqlCeConnection con = new SqlCeConnection(ConString))
{
CmdString = "SELECT products_id FROM products_to_categories where categories_id=" + categories_id;
SqlCeCommand cmd = new SqlCeCommand(CmdString, con);
DataTable dt = new DataTable();
SqlCeDataAdapter adapter = new SqlCeDataAdapter(cmd);
adapter.Fill(dt);
return dt;
}
}
how to show all the rows instead of one row in datagridview
CHANGED Try changing your foreach loop to:
DataTable dt = db.getProductIdFromCategoriesId(categories_id);
DataTable dt5 = new Datatable();
foreach (DataRow row in dt.Rows)
{
string products_id = row["products_id"].ToString();
dt5.Merge(db.FillDataGridfromTree(int.Parse(products_id)));
}
show_products.ItemsSource = dt5.DefaultView;
You code is always going to display the last row for a category_id, this is because you're assigning an ItemsSource inside a loop. I've changed the top part to do what you looking for:
DataTable dt = db.getProductIdFromCategoriesId(categories_id);
List<DataRow> ProductList = new List<DataRow>();
foreach (DataRow row in dt.Rows)
{
string products_id = row["products_id"].ToString();
DataTable dt5 = db.FillDataGridfromTree(int.Parse(products_id));
if(dt5.Rows.Count > 0)
{
ProductList.AddRange(dt5.Select().ToList());
}
}
show_products.ItemsSource = ProductList.CopyToDataTable().DefaultView;
This value (val1) I'm passing through url (I mean this operation as jobong filter option in checkbox list, filtering by selection index then passing through another page and retrieve through database):
Default Page 3: /WebSite4/Default4.aspx?vaL1=blue,red
This retrieving form page to view in page.
Default Page 2:
public void grid()
{
con.Open();
cmd = new SqlCommand("select * from lady_cloth where color in('" + Request.QueryString["vaL1"] + "')", con);
SqlDataAdapter da1 = new SqlDataAdapter(cmd);
DataSet ds3 = new DataSet();
da1.Fill(ds3);
con.Close();
if (ds3.Tables[0].Rows.Count > 0)
{
GridView1.DataSource = ds3;
GridView1.DataBind();
}
else
{
}
}
SqlConnection con = new SqlConnection("Data Source=xxxx;Initial Catalog=e_commerce;User ID=sa;Password=xxx");
SqlCommand cmd = new SqlCommand();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Label1.Text = Request.QueryString["Item"];
//Label2.Text = Request.QueryString["Color"];
//grid();
var colourTable = new DataTable();
colourTable.Columns.Add("Value", typeof(string));
var colours = Request.QueryString["vaL1"].Split(',');
for (int i = 0; i < colours.Length; i++)
{
var newRow = colourTable.NewRow();
newRow[0] = colours[i];
colourTable.Rows.Add(newRow);
}
}
string sql = "SELECT * FROM lady_cloth WHERE color IN (SELECT Value FROM #Colours)";
cmd = new SqlCommand(sql, con);
DataSet ds3 = new DataSet();
using (var adapter = new SqlDataAdapter(sql, con))
{
var parameter = new SqlParameter("#Colours", SqlDbType.Structured);
//parameter.Value = colourTable;
parameter.TypeName = "dbo.StringList";
cmd.Parameters.Add(parameter);
con.Open();
adapter.Fill(ds3);
}
if (ds3.Tables[0].Rows.Count > 0)
{
GridView1.DataSource = ds3;
GridView1.DataBind();
}
else
{
}
}
I think your problem is that you are not separating your items, so your SQL ends up looking like:
select *
from lady_cloth
where color in('blue,red')
Whereas what you would really want is
select *
from lady_cloth
where color in('blue','red')
If you are using SQL Server 2008 or later then I would recommend using table-valued parameters. The first step would be to create your type:
CREATE TYPE dbo.StringList TABLE (Value NVARCHAR(MAX));
I tend to just create generic types that can be easily reused, but this would be your call.
Then in your method you would need to split your values into an array and add them to a datatable:
var colourTable = new DataTable();
colourTable.Columns.Add("Value", typeof(string));
var colours = Request.QueryString["vaL1"].Split(',');
for (int i = 0; i < colours.Length; i++)
{
var newRow = colourTable.NewRow();
newRow[0] = colours[i];
colourTable.Rows.Add(newRow);
}
You can then add this table to your command as a parameter:
string sql = "SELECT * FROM lady_clock WHERE Color IN (SELECT Value FROM #Colours)"
cmd = new SqlCommand(sql, con);
var parameter = new SqlParameter("#Colours", SqlDbType.Structured);
parameter.Value = colourTable;
parameter.TypeName = "dbo.StringList";
cmd.Parameters.Add(parameter);
Finally, You can reduce your code by just initialising the SqlDataAdapter with your SQL and connection:
public void grid()
{
var colourTable = new DataTable();
colourTable.Columns.Add("Value", typeof(string));
var colours = Request.QueryString["vaL1"].Split(',');
for (int i = 0; i < colours.Length; i++)
{
var newRow = colourTable.NewRow();
newRow[0] = colours[i];
colourTable.Rows.Add(newRow);
}
string sql = "SELECT * FROM lady_clock WHERE Color IN (SELECT Value FROM #Colours)"
DataSet ds3 = new DataSet();
using (var adapter = new SqlDataAdapter(sql, con))
{
var parameter = new SqlParameter("#Colours", SqlDbType.Structured);
parameter.Value = colourTable;
parameter.TypeName = "dbo.StringList";
adapter.Parameters.Add(parameter);
con.Open();
da1.Fill(ds3);
}
if (ds3.Tables[0].Rows.Count > 0)
{
GridView1.DataSource = ds3;
GridView1.DataBind();
}
else
{
}
}
I had datagridview control which retrieves data from database. I had my code to do that, but no data apeared in gridview. I made a break point in the loop but when on DataGridViewTextBoxCell Number = (DataGridViewTextBoxCell)DGCategory.Rows[i].Cells[l];
datagrid view apeared with no data
private void getcategory()
{
for (int i = 0; i < DGCategory.Rows.Count; i++)
{
for (int l = 0; l < DGCategory.Rows[i].Cells.Count; l++)
{
DataGridViewTextBoxCell Number = (DataGridViewTextBoxCell)DGCategory.Rows[i].Cells[l];
DataGridViewTextBoxCell Category = (DataGridViewTextBoxCell)DGCategory.Rows[i].Cells[l];
DataGridViewTextBoxCell Parent = (DataGridViewTextBoxCell)DGCategory.Rows[i].Cells[l];
DataGridViewCheckBoxCell Active = (DataGridViewCheckBoxCell)DGCategory.Rows[i].Cells[l];
DataGridViewTextBoxCell AddDate = (DataGridViewTextBoxCell)DGCategory.Rows[i].Cells[l];
using (SqlConnection Con = GetConnection())
{
SqlCommand cmd = new SqlCommand("SP_GetAllCategories", Con);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataReader dr;
dr = cmd.ExecuteReader();
if (dr.Read())
{
Number.Value = dr["Number"].ToString();
Category.Value = dr["Category"].ToString();
Parent.Value = dr["Parent"].ToString();
Active.Value = dr["Active"].ToString();
AddDate.Value = dr["AddDate"].ToString();
}
}
}
}
}
If u want to get values from your database into a grid view .. use the following:
write your query in a String called "selectCommand" for example then use a dataset to get the results:
public DataSet GetSearchEmpResults(string emp_fn)
{
string selectCommand = #"select
emp.first_name as 'First Name',
emp.last_name as 'Last Name'
from Employees emp
where emp.first_name = '" + emp_fn + "';";
SqlCommand command = new SqlCommand(selectCommand, this.Connection);
DataSet ds = new DataSet("Results");
SqlDataAdapter da = new SqlDataAdapter(command);
da.Fill(ds, "Results");
return ds;
}
then in the data gridview code:
DataSet results = db.GetSearchEmpResults(fristName, lastName); //this depends on your results
dataGridViewResults.DataSource = results;
dataGridViewResults.DataMember = "Results";
the dataGridViewResults is the name of the data gridview you want your results yo appear in.
Note that you should provide the connection to your database in order to receive the results.