Question Binding Navigator SaveItem Question

dorkboy

Member
Joined
May 8, 2008
Messages
6
Programming Experience
10+
I am creating my first app in vb.net.

I have created a data source, selected "Details" and dropped the fields onto a Windows form.



Via the navigator, I go backwards, forwards, edit, etc just fine.



Question:

I Edit a record and click the Save button on the Binding Navigator. How can I find out which record was edited and saved (ie get the Primary Key for the record being saved)?



Currrently, all I have is the system generated code which looks like this:



Private Sub Dummy1BindingNavigatorSaveItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Dummy1BindingNavigatorSaveItem.Click

Me.Validate()
Me.Dummy1BindingSource.EndEdit()
Me.TableAdapterManager1.UpdateAll(Me.DataSet1)


End Sub



Thanks in advance for your help.
 
You really shouldn't be saving after every change. The whole point of this line:
VB.NET:
Me.TableAdapterManager1.UpdateAll(Me.DataSet1)
is that it will save every row that has changed in every table. It doesn't make sense that there'd be a way to get the ID of a single row that was saved given that.

That said, you can call GetChanges on your DataTable BEFORE saving and the result will contain all the rows that WILL BE saved.
 
I think the method is called Update() rather than UpdateAll(), unless VB generates differnet code to C#

See the DW2 link in my sig, though nnote it is for .NET 2 and you have 3. 3 specific sections are available and you should follow them where possible


Note2: You can as jmc says, call GetChanges. You can also Update() the DataRow() you get from GetChanges(), and then I think you'd call Merge to get them to merge in. Merge uses an internal index (i think) so it is unaffected by e.g. a database op recalculating a primary key

To have the tableadapter automatically detect primary keys that are calculated by the db, you need to sue a databse technology that supports multiple commands per statement
 
I think the method is called Update() rather than UpdateAll(), unless VB generates differnet code to C#
The TableAdapterManager is new in VS 2008. I've never actually used one but I assume that they allow you to perform operations on a group of associated TableAdapters at the same time. That would explain the UpdateAll method as opposed to individual Update methods.
 
Might be time to upgrade then, as it has irked me somewhat that TableAdapter doesnt inherit from anything and is hence a little difficult to manipulate .. That kinda implies that they do have a common ancestor that can be used to perform things more easily
 
Might be time to upgrade then, as it has irked me somewhat that TableAdapter doesnt inherit from anything and is hence a little difficult to manipulate .. That kinda implies that they do have a common ancestor that can be used to perform things more easily
Not so. TableAdapters don't inherit anything because each one is generated ad hoc to support a specific DataTable. If you look inside a TableAdapter it's simply a wrapper for a DbConnection and DbDataAdapter. Methods like Fill and Update are just pass-through methods for the corresponding members of the internal DbDataAdapter.

If you want to customise a TableAdapter you need to add a partial class and put your custom code in there. That way it won't be lost if the Data Source is reconfigured and the typed DataSet regenerated. I did just that once to add a pass-through property for the internal DbDataAdapter's AcceptChangesDuringUpdate property.
 
Not so. TableAdapters don't inherit anything because each one is generated ad hoc to support a specific DataTable.
Indeed, but given that every one has an Update, Fill, and a few other recycled terms, I dont see why they cant inherit from an ancestor or implement an interface, and it would make it easier to address them in a generic style for operations like accessing the internal adapter, enrolling it in a transaction etc.. currently if I want to do that without using transactionscope (because it sucks on oracle), I must use reflection.. If I can reflect, then I ought to be able to work with a parent that has all the properties..

So VS2008 tableadapters neither inhereit nor implement anything, and as just as inflexible in this regard as 2005?

Poor. Very poor.
 
Indeed, but given that every one has an Update, Fill, and a few other recycled terms
That's not true either. A TableAdapter will only have an Update method if the system can generate the SQL code for at least an InsertCommand, which may not be possible. A TableAdapter might perform a query containing a join. As such no non-query commands will be generated and therefore no Update method will be generated. As for a Fill method, that's just the default name for the default query. There's no reason you have to accept that default name and there's no reason you even have to have a default query, i.e. one that takes no parameters and returns all rows. You may have no need of such a query so you might do away with it and just have a FillBySomeColumn method that takes a parameter to filter on SomeColumn.

What you suggest might seem convenient but it's just not possible because TableAdapters can differ too much. Anyway, if you want to write generic data access code I don't really think you should be using TableAdapters anyway. Also, as I said, you can add your own partial class to expose the internal DbDataAdapter if you want. You can then write generic code using that.
 
That's not true either.
I see your point, but you make out like it's impossible to test whether a given class that descends from its parent actually implements functionality exposed by the parent

As for a Fill method, that's just the default name for the default query. There's no reason you have to accept that default name and there's no reason you even have to have a default query, i.e. one that takes no parameters and returns all rows.
True. Please understand that I'm not intending for this discussion to exhaustively list everything I'd like to see on a parent TableAdapter so that you can pick them off one by one. It's intended to purport that some things such as enrolling XXXTableAdapter in a transaction, without using tranactionScope (because they suck for oracle peeps), and other generic usages would be helped along if TableAdapter had a common ancestor. I dont particularly want to write a partial class for every one of the 400 tableadapters in this program when having a generic parent would work just fine

What you suggest might seem convenient but it's just not possible because TableAdapters can differ too much.
Not so much that they must descend from something so generically useless that it doesnt represent the design goal of a TA at all. There are some thigns that all TAs have, and it would be handy to have those as ancestor members. Have a google around for the reflective code needed to make transactions work without Partialling every single TA or TransactionScoping

Anyway, if you want to write generic data access code I don't really think you should be using TableAdapters anyway. Also, as I said, you can add your own partial class to expose the internal DbDataAdapter if you want. You can then write generic code using that.

That would be nearly a complete waste of time in using the designer at all. DataSet has descendents created by the designer, and typed DSs can be passed around as generic DataSet usually with an accompanying string member to indicate the table to use (for example)

I'd hoped that TableAdapters would inherit, as there are a number of things that I ahve come across during my extensive use of them that would have been made much easier if I could refer to them generically.. Cheeky as it may be to propose, I do kinda think I know what I'm talking about within my context..(because I know it, and I know TableAdapters) :)
 
Back
Top