Updating Datatable as Datasource - vb.net

I'm using a data table as a data source for a data grid in VB.NET.
Public Property InterimLotTable As DataTable
uxDataGridAuditSamplerView.DataSource = SamplerParent.InterimLotTable
But when I update the SamplerParent.InterimLotTable its not reflected in my dataGrid.
Here is the code where I update the Datatable.
Dim sql = String.Format("select * from CAMS.VW_BL_TAS_InterimLotData where PARENTLOT = '{0}'", ParentLot)
Dim dynaset = db.CreateDynaset(sql, DBWrapper.DynasetOptions.ORADYN_READONLY)
InterimLotTable = dynaset.CopyToDataTable()
I thought that with the databinding when I made changes to the InterimLotTable the datagrid would be updated automatically.

You're not updating InterimLotTable, you're replacing it - i.e. the property now returns a different object.
The controls that are bound to the old object don't know anything has happened, as the object they have a reference to, hasn't changed.
You could use an intermediate BindingSource, or raise an event so the UI can choose to rebind as appropriate

Related

Update Listbox after inserting a row in database

I have a listbox which has a bindingsource which connects to access database. have following code which creates and adds new line to my access database and to datagrid view but changes are not updating in the listbox.
Dim drv As DataRowView = DirectCast(EQtblBindingSource.AddNew(), DataRowView)
drv.BeginEdit()
drv.Row.BeginEdit()
drv.Row("eiD") = "SS"
drv.Row("EQ_NAME") = "DUMMY"
drv.Row.EndEdit()
drv.DataView.Table.Rows.Add(drv.Row)
EQ_tblTableAdapter.Update(EQDATADataSet.EQ_tbl)
EQtblBindingSource.ResetBindings(True)
Is there a way to reflect changes immediately after i add a new row? resetbindings seems not working or another option to reload or refresh my listbox. Any idea please help.
Thanks
Make sure that the DataSource for your listbox is set to the bindingsource.
Your code can be simplified to this:
With EQtblBindingSource
.AddNew()
DirectCast(.Current, DataRowView)("eiD") = "SS"
DirectCast(.Current, DataRowView)("EQ_NAME") = "DUMMY"
.EndEdit()
End With
EQ_tblTableAdapter.Update(EQDATADataSet.EQ_tbl)

Error when trying to add a row to an already existing data table and grid view

I currently have a gridview that I am able to populate with a query. On a button click I would like to run the query again with a new value and add the new information to what is already displayed in the gridview. I am attempting to do this by copying the information that is currently in the gridview into a datatable then adding a row to the table then resetting the binding on the gridview and refreshing the gridview. The problem is I get an error when trying to add the new row (System.Data.NoNullAllowedException: 'ColumnName' does not allow nulls.
Here is the code I am trying to use for this process. Any help would be much appreciated.
Dim EpicorCM As New SqlCommand(JobSelect, EpicorCon)
EpicorCon.Open()
Dim EpicorReader As SqlDataReader = EpicorCM.ExecuteReader
Dim JobInfoTable As New DataTable
JobInfoTable = CType(dgvJobInfo.DataSource, DataTable).Copy
JobInfoTable.Rows.Add(EpicorReader)
dgvJobInfo.AutoGenerateColumns = True
dgvJobInfo.DataSource = JobInfoTable
dgvJobInfo.Refresh()
EpicorCon.Close()
You are trying to add a SqlDataReader to the Rows collection but that will not work. It only compiles because the Add() method has an overload that is params of Object.
Fortunately DataTable has a method to load a reader. Instead of this:JobInfoTable.Rows.Add(EpicorReader), do this:
JobInfoTable.Load(EpicorReader)
As an aside, commands and readers are Disposable resources so you can leak memory by not disposing of them either in Using blocks or in Finally blocks.

Can I call SaveChanges when using raw SQL Query in EF6

I want to use sql raw query for better performance.
I was wondering if I could use context the same way as if I committed a query with linq. If I bind collection to dgv.DataSource and made some (update) could I call db.SaveChanges() to store the data in the database.
Example:
Using context = New BloggingContext()
Dim blogs = context.Blogs.SqlQuery("SELECT * FROM dbo.Blogs").ToList()
datagridview1.dataSource = blogs
' if I made some changes in datagridview1 could I
' use SaveChanges to commit any changes on button click
context.SaveChanges()
End Using
The DbSet.SqlQuery method returns object that are tracked by the context :
By default, the entities returned are tracked by the context (MSDN)
(note that Database.SqlQuery results never tracked by the context)
If you change your entities using Entity Framework the SaveChanges method will persist changes.
Using context = New BloggingContext()
Dim blogs = context.Blogs.SqlQuery("SELECT * FROM dbo.Blogs").ToList()
blogs.First().Title = "new Title"
context.SaveChanges() ' new Title will be persisted on database
End Using
By the way, depending on the kind of datagridview you are using (webform, winform, WPF, etc.), you will have to attach the modified entities to the context that will be used to save changes.

The data source does not support sorting

I have a Dynamic Data LINQ to SQL ASP.Net Website in VB.NET, and am having a little trouble with Sorting of my GridView and a Search routine I have implemented. On Page_Load, the GridView is sorted by a field (Departments.department) in ASC order. However, when I perform a search using the code below, I get an error
The Data Source Does Not Support Sorting.
I'm assuming the problem comes when the Page_Load event tries to sort the data after a Search is made, because of the DataSource/ID.
Dim button = DirectCast(sender, Button)
If button.ID = btnMultiColumnSearchClear.ID Then
txbMultiColumnSearch.Text = [String].Empty
Else
Using Data As New wcPhonesDataContext()
Dim EmployeeNameString As String = txbMultiColumnSearch.Text
Dim SearchResults = Data.Employees.Where(Function(Employees) Employees.Employee.Contains(EmployeeNameString))
GridView1.DataSourceID = ""
GridView1.DataSource = SearchResults
GridView1.DataBind()
End Using
End If
SOLVED, but now I have a new problem, here is the code I used to solve this issue...
Dim button = DirectCast(sender, Button)
If button.ID = btnMultiColumnSearchClear.ID Then
txbMultiColumnSearch.Text = [String].Empty
Else
Using Data As New wcPhonesDataContext()
Dim EmployeeNameString As String = txbMultiColumnSearch.Text
Dim SearchResults = Data.Employees.Where(Function(Employees) Employees.Employee.Contains(EmployeeNameString))
GridView1.Sort("", SortDirection.Ascending)
GridView1.DataSourceID = ""
GridView1.DataSource = SearchResults
GridView1.DataBind()
End Using
End If
I have created a new error though. It occurs if I perform a second search without going BACK to the Employees table.
'GridView1' fired event Sorting which wasn't handled.
If you use a SqlDataSource and connect the gridview to the data source with a datasourceid, then sorting is done for you magically. You don't have to do anything to support it.
But if set the datasource to some object that you have created in code, sorting does NOT magically happen for you. When the user clicks on a column head, this fires an OnSorting event. You have to write code to handle the event. Typically this mean regenerating the data in the desired order, or regenerating the data and then sorting it.
For example, if you generate the data with a SQL query, I sometimes create a function that runs the SQL query and returns a DataSet. This function takes the sort field as a parameter, which it pastes into the SQL query. Then for the initial display call this function passing in the default sort order, and for the OnSorting call this function passing in the desired sort field.

Making multiple copies of a data bound object from a DataGridView - how to decouple them?

I have a DataGridView object to which I've bound a list of objects (of type Asset) returned from a database query.
I'm programming in VB using Visual Studio 2005.
I want to grab two copies of the bound object (calling them oldAsset and newAsset) from the selected row in the DataGridView, update newAsset based on input from other controls on the form, and pass both oldAsset and newAsset to a function that will update the appropriate record in the DB.
I try to grab the two copies like this:
Dim currentRow As DataGridViewRow = Me.AssetDataGridView.CurrentRow
Dim newAsset As Asset
newAsset = currentRow.DataBoundItem
Dim oldAsset As Asset
oldAsset = currentRow.DataBoundItem
Opening a watch window on oldAsset and newAsset indicates that the appropriate values are pulled at this point. But when I try to change a property of just newAsset, like
newAsset.CurrentLocationID = cboLocations.SelectedValue
I see that the corresponding value in oldAsset is also changed. This is not what I want, but it's obviously what I'm telling the computer to do.
How do I tell the computer to do what I want?
Thanks in advance!
Found out what was wrong. Wasn't the data binding at all.
newAsset and oldAsset were shallow copies. I wanted deep copies.
I implemented ICloneable, wrote a Clone() function that did the memberwise copy, and wrote
Dim oldAsset As Asset
oldAsset = currentRow.DataBoundItem
Dim newAsset As Asset = oldAsset.Clone()