How to update GridView with multiple tables - c#

I have a DevExpress GridView with EditingMode = EditFormInplace.
I try to update GridView with multiple tables and get error
Dynamic SQL generation is not supported against multiple base tables
I think, it is nessesary to add UpdateCommand to the dataAdapter. But I don't understand how to get the parameters values for the Update query (from edited row).
What is the correct way to update DataSource with multiple (joined) tables?
Code:
public Form2()
{
InitializeComponent();
dataAdapter = new SqlDataAdapter("select t.Id, t.DT, t.Name, t.Age, l.SecondName from TestTime t left join TestTimeLinked l on l.Id = t.Id", Properties.Settings.Default.MARKETConnectionString);
SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter);
DataTable table = new DataTable();
table.Locale = System.Globalization.CultureInfo.InvariantCulture;
dataAdapter.Fill(table);
bindingSource1.DataSource = table;
gridControl1.DataSource = bindingSource1;
}
private void gridView1_RowUpdated(object sender, DevExpress.XtraGrid.Views.Base.RowObjectEventArgs e)
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.MARKETConnectionString))
{
conn.Open();
dataAdapter.Update((DataTable)bindingSource1.DataSource);
}
}

DataRow r = gridView1.GetDataRow(e.RowHandle); to get edited row values.
And completely method code:
private void gridView1_RowUpdated(object sender, DevExpress.XtraGrid.Views.Base.RowObjectEventArgs e)
{
DataRow r = gridView1.GetDataRow(e.RowHandle);
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.MARKETConnectionString))
{
conn.Open();
dataAdapter.UpdateCommand = conn.CreateCommand();
dataAdapter.UpdateCommand.CommandText = "UPDATE TestTimeLinked set SecondName = #Name where Id = #Id";
dataAdapter.UpdateCommand.Parameters.AddWithValue("Name", r.Field<string>("SecondName"));
dataAdapter.UpdateCommand.Parameters.AddWithValue("Id", r.Field<int>("ID"));
dataAdapter.UpdateCommand.ExecuteNonQuery();
}
}

Related

How to print selected row from DataGridView in C# with SQL

Using the following code the first row in SQL is printed only, How can I print selected row from DataGridView in C# with SQL:
public partial class PrintScreen : Form
{
SqlConnection con = new SqlConnection(#"Server = TEST;DataBase=Registration;Integrated Security=true;");
SqlDataAdapter da;
DataTable dt = new DataTable();
public PrintScreen()
{
InitializeComponent();
da = new SqlDataAdapter("select * from data_graduation", con);
da.Fill(dt);
this.dataGridView1.DataSource = dt;
}
private void Print_ys_ar_cert_Click(object sender, EventArgs e)
{
Print_ys_ar_cert frm = new Print_ys_ar_cert();
da = new SqlDataAdapter("select * from data_graduation where ID_gra = '" + dataGridView1.CurrentRow.Cells[0].Value.ToString() + "'", con);
da.Fill(frm.RegistrationDataSet1.data_graduation);
frm.reportViewer2.RefreshReport();
frm.Show();
}
}
Currently you are passing value of Cells[0] of first row of the grid, you need to pass value of selected row:
if(dataGridView1.SelectedRows.Count>0)
{
var selectedValue = dataGridView1.SelectedRows[0].Cells[0].ToString();
//rest of code
}
Since you have loaded the row from database once, you don't need to load it again from database, you can simply add it to the data table which is data source of the report this way:
var row = ((DataRowView)(dataGridView1.SelectedRows[0].DataBoundItem)).Row;
frm.RegistrationDataSet1.data_graduation.Rows.Add(row.ItemArray);
//rest of code

The data source does not support server-side data paging. .toList() is not working

I'm trying to load some data from a database, and to filter them using this method.
Now, i want also to show them by pages, especially at the non-filtered part.
I used a DataAdaptor to fill up a dataset table, on which I'm making my filtering.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
OracleConnection con = new OracleConnection(CS);
string query = "select * from table1";
OracleDataAdapter dataAdapter = new OracleDataAdapter(query, con);
DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet, "mytbl");
Session["DATASET"] = dataSet;
GridView1.DataSource = from dataRow in dataSet.Tables["mytbl"].AsEnumerable()
orderby dataRow["ID"]
select new guards
{
ID = Convert.ToInt32(dataRow["ID"]),
Nume = dataRow["NUME"].ToString()
};
GridView1.AllowPaging = true;
GridView1.DataBind();
}
You will have to tell ASP.NET how to page. in this case it is .Skip().Take()

How to populate a combo box from another combo box in the same form?

Two comboBox and a table called MAINCATE is created.
I have a code , but stuck to determine what SQLQuery should i use to get the second combo box filled , determined by the first combo box.
I just need a little help on how to fill in the second combobox based on mainCate picked by the first combobox..
i need to do something like.. if combobox 1 mainCate is "Food" , then combo box 2 should show "Raw , cooked , fruits and vegetables"
This is what is inside of the MAINCATE table -
(http://i.imgur.com/qR90Z2B.png)
And this is my code :-
DataSet ds1;
DataSet ds2;
public User()
{
InitializeComponent();
}
private void User_Load(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection();
conn.ConnectionString = "Data Source=PEWPEWDIEPIE\\SQLEXPRESS;Initial Catalog=master;Integrated Security=True";
conn.Open();
SqlDataAdapter daMain = new SqlDataAdapter("SELECT * FROM MAINCATE", conn);
ds1 = new DataSet();
daMain.Fill(ds1, "Maincate");
mainCatU.DisplayMember = "mainCate";
mainCatU.ValueMember = "mainCate";
mainCatU.DataSource = ds1.Tables["MAINCATE"];
mainCatU.DropDownStyle = ComboBoxStyle.DropDownList;
mainCatU.Enabled = true;
SqlDataAdapter daSub = new SqlDataAdapter("SELECT >What should i do here?<", conn);
ds2 = new DataSet();
daSub.Fill(ds2, "Subcate");
subCatU.DisplayMember = "Subcat1";
subCatU.ValueMember = "Subcat";
subCatU.DataSource = ds2.Tables["MAINCATE"];
subCatU.DropDownStyle = ComboBoxStyle.DropDownList;
subCatU.Enabled = true;
conn.Close();
}
private void mainCatU_SelectionChangeCommitted(object sender, EventArgs e)
{
//have no idea if a code should be here..
}
or should i do something like this?
SqlCommand cmd = new SqlCommand("select Subcat1,Subcat2,Subcat3,Subcat4 from MAINCATE where mainCate=#mainCate;", con);
=========================================
#philip -
putting this on page load repalcing my code above - it didnt work..
string result = mainCatU.SelectedItem.ToString();
SqlDataAdapter daSub = new SqlDataAdapter("SELECT * FROM MAINCATE where mainCate = " + result , conn);
ds2 = new DataSet();
daSub.Fill(ds2, "Subcate");
subCatU.DisplayMember = "Subcat1";
subCatU.ValueMember = "Subcat1";
subCatU.DataSource = ds1.Tables["MAINCATE"];
subCatU.DropDownStyle = ComboBoxStyle.DropDownList;
subCatU.Enabled = true;
even tried
SqlDataAdapter daSub = new SqlDataAdapter("SELECT * FROM MAINCATE where mainCate=#result", conn);
Actually, you don't need another sql query,because you already get all maincate records from database.You can simply use dictionary to store this records.
First define a Dictionary<string,List<string>>
Define it here(!)
DataSet ds1;
DataSet ds2;
Dictionary<string,List<string>> allRecords = new Dictionary<string,List<string>>();
Then: (i edit your code)
SqlDataAdapter daMain = new SqlDataAdapter("SELECT * FROM MAINCATE", conn);
ds1 = new DataSet();
daMain.Fill(ds1, "Maincate");
DataTable dt = ds1.Tables["MAINCATE"];
foreach (DataRow dr in dt.Rows)
{
List<string> SubCats = new List<string> {
dr["Subcat1"].ToString(),
dr["Subcat2"].ToString(),
dr["Subcat3"].ToString(),
dr["Subcat4"].ToString()
};
allRecords.Add(dr["mainCate"].ToString(),SubCats);
mainCatU.Items.Add(dr["mainCate"].ToString());
}
mainCatU.DropDownStyle = ComboBoxStyle.DropDownList;
mainCatU.Enabled = true;
Then you need to handle mainCatU selectionchanged like this:
if(allRecords.ContainsKey(mainCatU.SelectedItem.ToString())) {
subCatU.DataSource = allRecords[mainCatU.SelectedItem.ToString()];
}
I think this is what your looking for:
Fill the first combo box with your current code.
Then to fill the second combo box you need to hook up the first combo box selectionchangecommitted. However why not just use the standard event?
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
//Here use if statements to capture what value is set
if (comboBox1.SelectedIndex = 1)
//If selected value is Vehicles
{
//Then SELECT * FROM MainCate WHERE MainCate = 'Vehicles'
//This is possibly incorrect as I don't know how your DBTable is structured
//Same code as before
//Set this data to the second combobox
}
}
OK? So look into implementing this, if you want to refactor this you could, rather than using IF statements you could parametrise -
string result = comboBox1.SelectedItem.ToString();
SELECT * FROM MainCate WHERE MainCate = result
Obviously this won't compile so don't copy then paste it, then come back saying it doesn't work. It needs to be implemented like you did before, but rather than hardcode the result each time, use the parameter.
Personally I wouldn't have this all in one class, however you may prefer this way.
ComboBox1, ComboBox2 -- you just want to populate ComboBox2 using ComboBox1 Select change. So, At first bind your ComboBox1. Then cretae an event for ComboBox1:
private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string value1 = ComboBox1 .SelectedValue.ToString();
LoadComboBox2 ();
}
And Get your ComboBox1 selected value and use it to populate ComboBox2 .
private void LoadComboBox2 ()
{
DataRow dr;
SqlConnection con = new SqlConnection(#"Data Source=name;Initial Catalog=dbName;User ID=sa;Password=sa123");
con.Open();
SqlCommand cmd = new SqlCommand("select id,name from table where id=#ID", con);
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
dr = dt.NewRow();
dr.ItemArray = new object[] { 0, "--Select--" };
dt.Rows.InsertAt(dr, 0);
ComboBox2 .ValueMember = "ID";
ComboBox2 .DisplayMember = "Name";
ComboBox2 .DataSource = dt;
con.Close();
}

creating Cascaded dropdowns(WinForm)

I am using below code to fill my combobox ,now usingcode is working and i am getting country combobox with country items,but If I write using code in comboBox1_SelectedIndexChanged than using code doesn't work,why is that so ? and because of this i am not getting state dropdown based on country selected ,how it should be done?
public partial class RegPatient : Form
{
DBHandling db = new DBHandling();
string cmbvalue="";
public RegPatient()
{
InitializeComponent();
using (DataTable dt = DBHandling.GetCountryDataTable())
{
comboBox1.DataSource = new BindingSource(dt, null);
comboBox1.DisplayMember = "CountryName"; //column to show in comboBox
comboBox1.ValueMember = "Code";
}//here the table is disposed
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
//using code not working here
}
private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
using (DataTable dt = DBHandling.GetStateDataTable(comboBox1.Text) )
{
// contine using dt
comboBox2.DataSource = new BindingSource(dt, null);
comboBox2.DisplayMember = "ProvinceName";
}//here the table is disposed
}
}
Code for getting datatable country and state
public static DataTable GetCountryDataTable()
{
DataTable countryTable = new DataTable();
using (OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=sonorepo.mdb")) //use your conn. string here
{
using (OleDbDataAdapter da = new OleDbDataAdapter(#"SELECT CountryName, Code FROM Country", con))
da.Fill(countryTable);
}
return countryTable;
}
public static DataTable GetStateDataTable(string countryCode)
{
DataTable stateTable = new DataTable();
using (OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=sonorepo.mdb"))
{
using (OleDbDataAdapter da = new OleDbDataAdapter(#"SELECT ProvinceName FROM Province where Country='" + countryCode + "'", con))
da.Fill(stateTable);
}
return stateTable;
}
Thanks in advance
in the method comboBox2_SelectedIndexChanged you cannot create a local DataTable and use it as the datasource. After your code leaves the using statement the DataTable will be destroyed, leaving comboBox2 without a data source.
Leave out the using statement:
DataTable dt = DBHandling.GetStateDataTable(comboBox1.Text)
You are probably just copying a reference to an existing DataTable. So why would you want to dispose it?
Delete the comboBox2_SelectedIndexChanged event and double click on the ComboBox2 to create the event again and check if the event is getting fired.
If its ASP.Net application check if you have set AutoPostBack property

Dynamically update combobox based on user selection

I am not sure how postback works on WinForms, but I want to allow the ComboBox to update based on the user selection.
Currently when I change the selection of my first ComboBox, it doesn't change the items in the second dropdown. (only showing the first item by default)
In what ways can O alter this?
Code to what I have:
public ContentUploader()
{
InitializeComponent();
using (SqlConnection con = new SqlConnection(conString))
{
con.Open();
using (SqlDataAdapter sda = new SqlDataAdapter("SELECT ... re.OverallID = 1", conString))
{
DataTable dt = new DataTable();
sda.Fill(dt);
sections_drp.ValueMember = "ID";
sections_drp.DisplayMember = "DisplayName";
sections_drp.DataSource = dt;
}
}
sections_drp.SelectedIndexChanged += (o, e) => FillFirstChildren();
}
public void FillFirstChildren()
{
firstChild_drp.Items.Add("Select Item");
firstChild_drp.SelectedIndex = 0;
string sectionId = sections_drp.SelectedValue.ToString();
using (SqlConnection con = new SqlConnection(conString))
{
con.Open();
using (SqlDataAdapter sda = new SqlDataAdapter("SELECT ... em.ItemID = ("+ sectionId +")", conString))
{
DataTable dt = new DataTable();
sda.Fill(dt);
firstChild_drp.ValueMember = "ID";
firstChild_drp.DisplayMember = "DisplayName";
firstChild_drp.DataSource = dt;
}
}
FillSecondChildren();
}
Winforms does not contain a post back. You will need to tie to the SelectedIndexChanged (or Item or Value) event to filter your second dropdown.
Example:
public void FillFirstChildren()
{
//Your Fill Logic Here
...
//Call FillSecondChildren on selection change
firstChild_drop.SelectedIndexChanged += (o, e) => FillSecondChildren();
}

Categories

Resources