{"id":4383,"date":"2008-05-14T19:52:00","date_gmt":"2008-05-14T19:52:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2008\/05\/14\/how-linq-to-dataset-works-in-vb-jonathan-aneja\/"},"modified":"2024-07-05T14:25:17","modified_gmt":"2024-07-05T21:25:17","slug":"how-linq-to-dataset-works-in-vb-jonathan-aneja","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/how-linq-to-dataset-works-in-vb-jonathan-aneja\/","title":{"rendered":"How LINQ to Dataset works in VB (Jonathan Aneja)"},"content":{"rendered":"<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\"><span>LINQ at its core requires any data source to be <i>queryable<\/i>, which basically means it must implement IEnumerable.&nbsp; (It&rsquo;s actually a bit more complicated than that, for a full explanation see section 11.21.2 of the<\/span><span> <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms234437.aspx\">Visual Basic 9.0 Language Specification<\/a>).&nbsp; <\/span><span>Now when working with LINQ to Dataset we have a problem: DataTable does <i>not<\/i> implement IEnumerable, so how can we query over it?<\/span><span><\/p>\n<p><\/span><\/font><\/font><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Calibri\" size=\"3\">As we saw <\/font><a href=\"http:\/\/blogs.msdn.com\/vbteam\/archive\/2008\/05\/13\/using-linq-to-dataset-in-an-aspx-page-jonathan-aneja.aspx\"><font face=\"Calibri\" size=\"3\">yesterday<\/font><\/a><font face=\"Calibri\" size=\"3\">, Visual Studio 2008 includes an assembly called System.Data.DataSetExtensions.dll, which defines an <\/font><a href=\"http:\/\/blogs.msdn.com\/vbteam\/pages\/articles-about-extension-methods.aspx\"><font face=\"Calibri\" size=\"3\">extension method<\/font><\/a><font size=\"3\"><font face=\"Calibri\"> called AsEnumerable().&nbsp; Here&rsquo;s what this method looks like:<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp; &lt;Extension()&gt; _<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp; <span>Public<\/span> <span>Function<\/span> AsEnumerable(source <span>As<\/span> DataTable) <span>As<\/span> EnumerableRowCollection(<span>Of<\/span> DataRow)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">Basically this takes in a DataTable and sends back something that implements IEnumerable(Of T), which LINQ can then consume using the standard query operators.&nbsp; So all you have to do is import System.Data (which is done by default in the project templates) and then you can use LINQ against a Dataset by calling AsEnumerable().&nbsp; <\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp; Dim<\/span><span> customers = TestDS.Tables(<span>&#8220;Customers&#8221;<\/span>)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span>Dim<\/span> franceCustomers = <span>From<\/span> cust <span>In<\/span> customers.AsEnumerable() _<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Where<\/span> cust!Country = <span>&#8220;France&#8221;<\/span> _<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Select<\/span> cust<\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">Now one of the interesting things about the way LINQ works in VB is you don&rsquo;t actually have to call AsEnumerable() explicitly for the code above to compile.&nbsp; Even though DataTable does not implement IEnumerable, the compiler helps out here by looking for methods that can turn it into something queryable.&nbsp; When the VB compiler encounters a LINQ query over a type that does not implement IEnumerable, IEnumerable(Of T), IQueryable, or IQueryable(Of T) it then does the following, in order:<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">1.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span><font size=\"3\"><font face=\"Calibri\">See if there is a conforming Select method available on the type.<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">2.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span><font size=\"3\"><font face=\"Calibri\">See if the type has an instance method named AsQueryable which returns a type that is queryable.&nbsp; <\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">3.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span><font size=\"3\"><font face=\"Calibri\">See if the type has an extension method in scope named AsQueryable which returns a type that is queryable.&nbsp; <\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">4.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span><font size=\"3\"><font face=\"Calibri\">See if the type has an instance method named AsEnumerable which returns a type that is queryable.&nbsp; <\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoListParagraph\"><span><span><font face=\"Calibri\" size=\"3\">5.<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span><font size=\"3\"><font face=\"Calibri\">See if the type has an extension method in scope named AsEnumerable which returns a type that is queryable.<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p><\/span><\/p>\n<p><font size=\"3\"><font face=\"Calibri\"><span>If at any point the compiler finds a method that matches, it inserts a call to it.&nbsp; When the System.Data namespace i<\/span>s imported, the compiler finds a match for DataTable on step <span>5,<\/span> and inserts the call to AsEnumerable for you.&nbsp; As a result you can write LINQ to Dataset code like this example from the <\/font><\/font><a href=\"http:\/\/msdn.microsoft.com\/en-us\/vbasic\/bb688088.aspx\"><font face=\"Calibri\" color=\"#0000ff\" size=\"3\">101 LINQ Samples<\/font><\/a><font size=\"3\"><font face=\"Calibri\">:<\/p>\n<p><\/font><\/font><\/p>\n<p class=\"MsoNormal\">\n<p><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Dim<\/span> customers = TestDS.Tables(<span>&#8220;Customers&#8221;<\/span>)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Dim<\/span> franceCustomers = <span>From<\/span> cust <span>In<\/span> customers _<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Where<\/span> cust!Country = <span>&#8220;France&#8221;<\/span> _<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span>Select<\/span> cust<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">What this means is that you can LINQ-enable your types by providing an AsEnumerable extension method that returns something that is queryable.<\/p>\n<p><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">Note that for strongly-typed Datasets you don&rsquo;t need to call AsEnumerable, as they inherit from TypedTableBase(Of T) which implements IEnumerable.<span>&nbsp; <\/span>This is a new type in VS2008; in VS2005 the Dataset Designer would generate code that inherited from DataTable and then explicitly implemented IEnumerable itself.<\/p>\n<p><\/font><\/font><\/span><\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>LINQ at its core requires any data source to be queryable, which basically means it must implement IEnumerable.&nbsp; (It&rsquo;s actually a bit more complicated than that, for a full explanation see section 11.21.2 of the Visual Basic 9.0 Language Specification).&nbsp; Now when working with LINQ to Dataset we have a problem: DataTable does not implement [&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":[53,67,83,94,117,165,166],"class_list":["post-4383","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-featured","category-visual-basic","tag-data_design","tag-extension_methods","tag-jonathan-aneja","tag-linqvb9","tag-orcas","tag-vb2005","tag-vb2008"],"acf":[],"blog_post_summary":"<p>LINQ at its core requires any data source to be queryable, which basically means it must implement IEnumerable.&nbsp; (It&rsquo;s actually a bit more complicated than that, for a full explanation see section 11.21.2 of the Visual Basic 9.0 Language Specification).&nbsp; Now when working with LINQ to Dataset we have a problem: DataTable does not implement [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/4383","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=4383"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/4383\/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=4383"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=4383"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=4383"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}