{"id":7163,"date":"2005-05-04T11:08:00","date_gmt":"2005-05-04T11:08:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2005\/05\/04\/how-to-extend-tableadapter-methods\/"},"modified":"2024-07-05T14:55:30","modified_gmt":"2024-07-05T21:55:30","slug":"how-to-extend-tableadapter-methods","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/how-to-extend-tableadapter-methods\/","title":{"rendered":"How to extend TableAdapter methods"},"content":{"rendered":"<p>A number of posts have asked how to extend TableAdapters to support additional functionality.&nbsp; It may be related to supporting transactions across multiple updates, or how do I set the UserId as a parameter on an update statement that isn&rsquo;t represented in the DataTable?<br \/>For Transactions, we don&rsquo;t expose a Transaction Property by default because this was tedious task in 1.x of the framework. With 2.0 we now have a great solution with System.Transactions.&nbsp; If you search this blog you&rsquo;ll see several references to using the new TransactionScope object to very easily wrap several TableAdapters in a single transaction that will automatically enlist DTC when needed, or simply leverage SQL 2005 transactions when working with a single database.<br \/>However, assuming you&rsquo;re leveraging an existing codebase you&rsquo;ve written in 1.x, or you have another request for the TableAdapters, you can simply take advantage of partial classes to add just about any functionality you&rsquo;d like.<br \/>In order to extend the TableAdapters you may need a little help knowing where\/how to extend them.&nbsp; In order to decouple the TableAdpaters from the DataSet they fill, we decided not to use nested classes for each TableAdapter.&nbsp; The next challenge was how do we find a unique namespace for each TableAdapter when you may very likely have several DataSets\/TableAdapter combinations with objects of the same name.&nbsp; For instance, one strategy is to create several smaller DataSets for each unit of work.&nbsp; This means you might wind up with an OrderDataSet that includes Customers, Orders, OrderItems, Products, etc..&nbsp; You then might have another DataSet for contacts which includes Customers, CompanyContacts, People, etc.&nbsp; In this case you&rsquo;d wind up with two CustomerTableAdapters.&nbsp; Without nested classes we need a model that would scale without simply concatenating a number to the end of each class.&nbsp; A goal of the Whidbey data features were Smart Defaults.&nbsp; The solution we came up with is to leverage namespaces.&nbsp; <br \/>To find your TableAdapters use the following pattern: [DataSetName] + TableAdapter.&nbsp; For the NorthwindDataSet, the namespace would be NorthwindDataSetTableAdapters.&nbsp; <br \/>The next question is how\/where to place this code?&nbsp; If you double click on a DataTable we&rsquo;ll automatically create the partial class for the DataTable and DataSet in the [DataSetName].designer.vb\/cs file.&nbsp; Unfortunately, we just didn&rsquo;t have the time to do the same thing for TableAdapters.&nbsp; While you could add the TableAdapter code to the [DataSetName].vb\/cs file, you may want to create a separate file just for your TableAdapters.<br \/>Using the Northwind database example, we&rsquo;ll extend the Orders table to include a UserId parameter.<br \/>In Solution Explorer select Add Item and choose a Class File.&nbsp; Name the class file, NorthwindDataSet.TableAdapters.vb or cs.<br \/>Replace the code with something similar to the following:<\/p>\n<p><font color=\"#0000ff\">Namespace NorthwindDataSetTableAdapters<br \/>&nbsp;&nbsp;&nbsp; Partial Class OrdersTableAdapter<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Public Overloads Function Update(ByVal ordersTable As NorthwindDataSet.OrdersDataTable, ByVal userId As Guid) As Integer<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Me.m_adapter.UpdateCommand.Parameters(&#8220;UserId&#8221;).Value = userId<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Me.m_adapter.InsertCommand.Parameters(&#8220;UserId&#8221;).Value = userId<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Return Me.Update(ordersTable)<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; End Function<br \/>&nbsp;&nbsp;&nbsp; End Class<br \/>End Namespace<\/font><\/p>\n<p>In the above example I&rsquo;m setting an additional parameter on the Update and Insert commands that do not map to a column in the orders data table.&nbsp; This parameter is used by my stored procedure for some change tracking.&nbsp; <\/p>\n<p>This should give a glimpse into the possibilities of extending the TableAdapters to your specific functionality.<br \/>Steve Lasker<br \/>Program Manager<br \/>Visual Studio Data Designtime<br \/>Blogs@ <a href=\"https:\/\/blogs.msdn.com:443\/vbteam\/archive\/category\/4754.aspx\">http:\/\/blogs.msdn.com\/vbteam\/archive\/category\/4754.aspx<\/a><\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A number of posts have asked how to extend TableAdapters to support additional functionality.&nbsp; It may be related to supporting transactions across multiple updates, or how do I set the UserId as a parameter on an update statement that isn&rsquo;t represented in the DataTable?For Transactions, we don&rsquo;t expose a Transaction Property by default because this [&hellip;]<\/p>\n","protected":false},"author":260,"featured_media":8818,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[192,195],"tags":[],"class_list":["post-7163","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-featured","category-visual-basic"],"acf":[],"blog_post_summary":"<p>A number of posts have asked how to extend TableAdapters to support additional functionality.&nbsp; It may be related to supporting transactions across multiple updates, or how do I set the UserId as a parameter on an update statement that isn&rsquo;t represented in the DataTable?For Transactions, we don&rsquo;t expose a Transaction Property by default because this [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/7163","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/users\/260"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/comments?post=7163"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/7163\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media\/8818"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media?parent=7163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=7163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=7163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}