Tree View Datagridview in devexpress - vb.net

I tried many times to create a master view of the table along with its details and visualize that in a Gridcontrol (from Devexpress)
here is the code
*I do not want to rely on the automatic generation of codes by Devexpress designer!
' DEFINE A DATASET TO HOLD TABLES INSIDE
Dim dataset As New DataSet
'IF THE CONNECTION IS POSSIBLE THEN PROCCEED
If sqlcontrol.HasConnection Then
' SELECT ALL RECORDS FROM THE SUPPLIERS TABLE (MASTER TABLE)
sqlcontrol.ExecQuery("SELECT * FROM [Suppliers]")
' FILL IN THAT TABLE INTO THE DATASET
dataset.Tables.Add(sqlcontrol.SQLdatatable)
' SELECT ALL RECORDS FROM THE SUPPLIERSPERSONNEL (DETAIL TABLE)
sqlcontrol.ExecQuery("SELECT * FROM [SuppliersPersonnel]")
'FILL IN THAT TABLE INTO THE DATASET
dataset.Tables.Add(sqlcontrol.SQLdatatable)
'INVOKE THE BINDING SOURCE INTO THE GRIDVIEW
Me.GridControl1.DataSource = dataset
End If
hopefully it worked but not like a master-detail view.
it showed every table on its own.

The Dataset itself indeed contains the tables, yet the relations between tables are missing and did not retrieved from the SQL tables, hence why this relationship needs to be added inside the Dataset in VB.
so the code is like the following:
' DEFINE A DATASET TO HOLD TABLES INSIDE
Dim dataset As New DataSet
'IF THE CONNECTION IS POSSIBLE THEN PROCCEED
If sqlcontrol.HasConnection Then
' SELECT ALL RECORDS FROM THE SUPPLIERS TABLE (MASTER TABLE)
sqlcontrol.ExecQuery("SELECT * FROM [Suppliers]")
' FILL IN THAT TABLE INTO THE DATASET
dataset.Tables.Add(sqlcontrol.SQLdatatable)
' SELECT ALL RECORDS FROM THE SUPPLIERSPERSONNEL (DETAIL TABLE)
sqlcontrol.ExecQuery("SELECT * FROM [SuppliersPersonnel]")
'FILL IN THAT TABLE INTO THE DATASET
dataset.Tables.Add(sqlcontrol.SQLdatatable)
'Add the relation to the dataset
dataset.relations.add("CustomRelation",
dataset.tables(0).columns(0),
dataset.tables(1).columns(1), false)
'INVOKE THE BINDING SOURCE INTO THE GRIDVIEW
Me.GridControl1.DataSource = dataset
End If
By such way, the Gridcontrol works as expected !

Related

Data Set is not filling data with newly added column when use SqlDataProvider.Fill Function

I am using Data Source and Data Table to retrieve Data for Report viewer. Currently I have a requirement to add new column to Data table. Therefore I added new column to the data table. But SqlDataProvider.Fill Function is not filling data for newly added column. I want to know how can I modify the data set when Data or store procedure got changed. enter image description here
string queryString =
"SELECT CustomerID, CompanyName FROM dbo.Customers";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);
DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");
For more detail check
https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/populating-a-dataset-from-a-dataadapter

Execption: Cannot create a DataRelation if Parent or Child Columns are not in a DataSet

i tried to create relashionship between two tables,
(access)
my code:
Dim DataSet1 As New DataSet("DataSet")
DataSet1.Tables.Add(getTable(TableName, con)) 'Returns DataTable
Dim DataRelation1 As DataRelation = New DataRelation(TableName, Column1, Column2, True) ' Execption Here !!!
DataRelation1.Nested = True
DataSet1.Relations.Add(obj_DataRelation)
Exception:
Cannot create a DataRelation if Parent or Child Columns are not in a DataSet.
I missed something?( yes but what :/ )(Example C# / VB.net is the best answer)
A relation must be between two tables. you need to have a DataSet with at least 2 Tables to set up a DataRelation.
The columns you're passing in, Column1 and Column2, either belong to different data sets or simply aren't both in the same data set.

Inserting multiple parent rows and multiple child rows for each parent with ADO.NET in one setting

I am looking for a howto or someone expert in ADO.NET who can explain me how to properly solve the following scenario:
I have two datatables in a dataset:
ParentTable (ParentID, Name) for user data
ChildTable (ParentID, ActivityID, ...) for schedule data
Tables are linked together at the database level by ParentID which is an Identity column in ParentTable.
Both tables are data bound to a separate DataGridView on the GUI. There supposed to be a "1 parent/N children" relationship between the tables, meaning if I create a new entry in the ParentTable (a new user) I get a clean DataGrid in the child grid to type schedule data for the user. So I setup two DataAdapters for each table to fill their result into a DataSet. I also set up a DataRelation object and assign it to the DataSet to link the two tables by their ParentID columns. Also when I add a row into the ChildTable via DataGrid I use SetParentRow to set the parent row.
With DAUser
.SelectCommand = New SqlCommand("UsersSelect", conn)
.SelectCommand.CommandType = CommandType.StoredProcedure
.SelectCommand.Parameters.AddWithValue("#UserID", MyID)
.Fill(DSData)
End With
With DAActivity
.SelectCommand = New SqlCommand("ActivitiesSelect", conn)
.SelectCommand.CommandType = CommandType.StoredProcedure
.SelectCommand.Parameters.AddWithValue("#UserID", MyID)
.Fill(DSData)
End With
DSData.Relations.Add(New DataRelation("UserActivity", DSData.Tables(0).Columns("ParentID"), DSData.Tables(1).Columns("ParentID")))
Adding row into the ChildTable:
Private Sub DTChildData_TableNewRow(sender As Object, e As System.Data.DataTableNewRowEventArgs) Handles DTChildData.TableNewRow
e.Row.SetParentRow(ParentDataRow)
End Sub
Still, the ParentID column in ChildTable is not populated with the Identity value retrieved from the DB when ParentTable is updated.
Why? I am starting to loose serious amount of hair over this problem...
A couple of notes:
1) The relation between the two tables is most likely incorrect, since you are referencing ParentID on both sides of the relationship. I am guessing that you need to change it to:
DSData.Relations.Add(New DataRelation("UserActivity", DSData.Tables(0).Columns("UserID"), DSData.Tables(1).Columns("ParentID")))
2) You aren't showing your insert or update commands, but if they are stored procedures and the UserID is generated in that stored procedure, then you will need to pass it back out of the stored procedure as an OUTPUT parameter. You will have to change both the SP and the parameter definition (if you have one) in the insert/updated command.

VB.NET Merge multiple tables and then update MS Access db

I am hitting an MS Access db with VB2005 and I am creating a table object like this
Dim sSQL As String = "SELECT * FROM tblCars WHERE WeekOf=#6/1/2011#"
Dim da As New OleDb.OleDbDataAdapter(sSQL, conn)
Dim ds As New DataSet
da.Fill(ds, "CarData")
Dim cb As New OleDb.OleDbCommandBuilder(da)
The table should have no rows since the data is brand new. I read a data text file with new data and pump this data into the table and add new rows like so:
'create a new empty row
Dim dsNewRow As DataRow = ds.Tables("CarData").NewRow()
'update the new row with fresh data
dsNewRow.Item("DriveDate") = dd
dsNewRow.Item("DCode") = dc
dsNewRow.Item("CarNum") = carID
'about 15 more fields
'add the filled row to the DataSet table
ds.Tables("CarData").Rows.Add(dsNewRow)
'end loop
'update the database with the new rows
da.Update(ds, "CarData")
The table in the db has no primary keys but all this works and i get all my new data inserted into the Data table tblCars.
Now it so happens that I must also account for cars with no data. For that my plan was to get a list of cars from the control table and merge it with the Data table.
Dim sSQL As String = "SELECT CarId FROM tblControlCars WHERE ActiveCar=True;"
Dim daAct As New OleDb.OleDbDataAdapter(sSQL, conn)
Dim ds As New DataSet
daTail.Fill(ds, "ActCars")
Dim cbAct As New OleDb.OleDbCommandBuilder(daAct)
I then create my primary keys for the tables and then merge them.
ds.Tables("CarData").Merge(ds.Tables("ActCars"))
This will give me a table with all the new data for cars that do have data and also a place holder for those cars that are active but did not get any data. However, when I try to do an update back to the db I get an error
System.InvalidOperationException: Dynamic SQL generation for the UpdateCommand is not supported against a SelectCommand that does not return any key column information.
I'm not sure I understand why the Merged data is not able to be pushed to the database.
I've had the same problem before just add a primary key in your database table , the command builder needs a unique identification field to generate a proper command .
You can simply create a field called "id" and make auto-number then you don't have to update it manually and make it a primary key that's it

when should dataset reflect the updated rows count after an insert in vb.net

i have a sql database, and have created a dataset for a sample table in it.
The dataset is HotelDataSet2 and data table adapter to insert to it is Various_itemsTableAdapter.
MsgBox(HotelDataSet2.various_items.Rows.Count)
Various_itemsTableAdapter.Insert(Item_nameTextBox.Text, itemcode, PackingTextBox.Text, UomTextBox.Text, PriceTextBox.Text, RemarksTextBox.Text, TaxTextBox.Text, StatusCheckBox.Checked, Rate_inclusiveCheckBox.Checked)
MsgBox(HotelDataSet2.various_items.Rows.Count)
This always reflects the same count, before and after inserting..But if i execute this
MsgBox(HotelDataSet2.various_items.Rows.Count)
Various_itemsTableAdapter.Insert(Item_nameTextBox.Text, itemcode, PackingTextBox.Text, UomTextBox.Text, PriceTextBox.Text, RemarksTextBox.Text, TaxTextBox.Text, StatusCheckBox.Checked, Rate_inclusiveCheckBox.Checked)
Various_itemsTableAdapter.Fill(HotelDataSet2.various_items)
MsgBox(HotelDataSet2.various_items.Rows.Count)
it shows the new count to be +1 of the old one. So i concluded that everytime i change some data to the table via table adapter, i have to always refill the dataset?? How is that useful then??
You're going about this the wrong way. You should be using the DataSet to make your changes (ie, create DataRow's with its tables and insert those rows into the table), then pass the appropriate DataTable from the DataSet to your TableAdapter in order to persist the changes to the database by calling the Update function on the TableAdapter
tableAdapter.Update(dataSetName);
Calling the Insert function directly only inserts that data into the table in the database itself; it does not have any effect on any local copies of the data (such as your DataSet).
As a side note, try to avoid using language-specific functions like MsgBox. Instead, to show a message box try calling MessageBox.Show(...), as that is language-independent.
Edit
To clarify, the proper way to do this is to create a new DataRow, populate its columns with the new values, add that DataRow to the appropriate table, then pass the table to the TableAdapter through the Update function.
For example, I have...
A DataSet named myDataSet
A DataTable in myDataSet called MyTable
A TableAdapter for MyTable called myTableAdapter
Two columns in that table, FirstName and LastName
Two TextBoxes called txtFirstName and txtLastName
To insert a row with those values, I would do this:
DataRow row = myDataSet.MyTable.NewRow(); // creates a new row with the correct columns
row["FirstName"] = txtFirstName.Text;
row["LastName"] = txtLastName.Text;
myDataSet.MyTable.Rows.Add(row); // adds the new row to the in-memory table
myTableAdapter.Update(myDataSet); // persists all of the changes to the DataSet