{"id":6813,"date":"2006-06-19T19:44:00","date_gmt":"2006-06-19T19:44:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2006\/06\/19\/vb6-collections-the-missing-linq\/"},"modified":"2024-07-05T14:52:33","modified_gmt":"2024-07-05T21:52:33","slug":"vb6-collections-the-missing-linq","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/vb6-collections-the-missing-linq\/","title":{"rendered":"VB6 Collections: The Missing LINQ"},"content":{"rendered":"<p><span><\/p>\n<p class=\"MsoNormal\"><span>By Jonathan Aneja<\/span><\/p>\n<p class=\"MsoNormal\"><b><span>&nbsp;<\/span><\/b><\/p>\n<p class=\"MsoNormal\"><span>Hi, my name\u2019s Jonathan and I\u2019m a Program Manager on the VB team, working mainly on LINQ features.<span>&nbsp; <\/span>One of the things I love about LINQ is it\u2019s not just limited to querying over databases and XML \u2013 you can query over any collection of Objects.<span>&nbsp; <\/span>For example, let\u2019s say I have a collection of PurchaseOrders, and I want to return the ones that meet the following criteria:<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<ol type=\"1\">\n<li class=\"MsoNormal\"><span>Ordered between June 12<sup>th<\/sup> and June 14<sup>th<\/sup><\/span>\n<li class=\"MsoNormal\"><span>Sorted by Date (ascending), then by Total (descending)<\/span><\/li>\n<\/ol>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>At this point you\u2019d have to write code to filter out the correct POs and then apply the double-sort criteria.<span>&nbsp; <\/span>With LINQ this simply becomes:<\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Times New Roman\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><span>Dim<\/span><span> query = <span>From<\/span> p <span>In<\/span> PurchaseOrders _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Where<\/span> p.OrderDate &gt;= #6\/12\/2006# <span>And<\/span> p.OrderDate &lt;= #6\/14\/2006# _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Select<\/span> p _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Order<\/span> <span>By<\/span> p.OrderDate, p.Total <span>Descending<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Times New Roman\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><span>Pretty cool so far, but if you\u2019re like me you\u2019re thinking \u201cWhat about all that old VB6 code I wrote?<span>&nbsp; <\/span>Can\u2019t I use LINQ on a VB6 Collection?\u201d<span>&nbsp; <\/span>The answer is a resounding yes, with a little help from our friend the VB Upgrade Wizard.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>To get started, let\u2019s say I have a function that returns a VB6 Collection of PurchaseOrders:<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>&#8216;Returns a Collection of PurchaseOrders<\/span><\/p>\n<p class=\"MsoNormal\"><span>Private<\/span><span> <span>Function<\/span> LoadPOs() <span>As<\/span> Collection<\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Times New Roman\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><span>When a VB6 project is opened with VS2005, the Upgrade Wizard migrates the project to .NET; after the conversion, the old VB6 collection is converted to the Microsoft.VisualBasic.Collection type. <span>&nbsp;<\/span>So now that the code\u2019s upgraded to .NET, how do we query against it?<span>&nbsp; <\/span>First we need to Import System.Query.Sequence:<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>Imports<\/span><span> System.Query.Sequence<\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Times New Roman\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><span>There\u2019s still one more issue though: LINQ requires collections to implement IEnumerable(Of T), and the VB6 Collection object doesn\u2019t.<span>&nbsp; <\/span>That\u2019s where LINQ\u2019s OfType() extension method saves the day:<\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Times New Roman\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&nbsp;<\/span><span>&#8216;Converts the Collection to an IEnumerable(Of PurchaseOrder)<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> PurchaseOrders = LoadPOs().OfType(<span>Of<\/span> PurchaseOrder)()<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> query = <span>From<\/span> p <span>In<\/span> PurchaseOrders _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Where<\/span> p.OrderDate &gt;= #6\/12\/2006# <span>And<\/span> p.OrderDate &lt;= #6\/14\/2006# _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp; <\/span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span>Select<\/span> p _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Order<\/span> <span>By<\/span> p.OrderDate, p.Total <span>Descending<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Times New Roman\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><span>OfType converts the VB6 Collection to an IEnumerable(Of PurchaseOrder), and just like that we can write any query we want.<span>&nbsp; <\/span>And the best part is, <i>we didn\u2019t have to change a single line of the code we wrote in VB6!<\/i> <\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>While we\u2019re at it, let\u2019s write a few more queries:<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> query2 = <span>From<\/span> p <span>In<\/span> query _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Where<\/span> p.Total &gt; 300 _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Select<\/span> p<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> query3 = <span>From<\/span> p <span>In<\/span> PurchaseOrders _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Where<\/span> p.Item &lt;&gt; <span>&#8220;Bicycle&#8221;<\/span> _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Select<\/span> p _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Order<\/span> <span>By<\/span> p.Total <span>Descending<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Times New Roman\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><span>Of course, now that we\u2019re in .NET we can take advantage of the rich functionality offered in System.Collections, in which case we don\u2019t even need to call OfType() anymore.<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>Want to try it for yourself? Download the <a href=\"http:\/\/www.microsoft.com\/downloads\/details.aspx?familyid=1e902c21-340c-4d13-9f04-70eb5e3dceea&amp;displaylang=en\">May 2006 LINQ CTP<\/a> and let us know what you think! There\u2019s a sample VB6 project and its upgraded .NET counterpart attached.&nbsp;You can find more information on LINQ at <a href=\"http:\/\/msdn.microsoft.com\/data\/ref\/linq\/\">http:\/\/msdn.microsoft.com\/data\/ref\/linq\/<\/a><\/span><\/p>\n<p><\/span><\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/MSDNBlogsFS\/prod.evol.blogs.msdn.com\/CommunityServer.Components.PostAttachments\/00\/00\/63\/77\/14\/VB6_to_LINQ.zip\">VB6_to_LINQ.zip<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>By Jonathan Aneja &nbsp; Hi, my name\u2019s Jonathan and I\u2019m a Program Manager on the VB team, working mainly on LINQ features.&nbsp; One of the things I love about LINQ is it\u2019s not just limited to querying over databases and XML \u2013 you can query over any collection of Objects.&nbsp; For example, let\u2019s say I [&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":[83,94,117,170],"class_list":["post-6813","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-featured","category-visual-basic","tag-jonathan-aneja","tag-linqvb9","tag-orcas","tag-vb6_migrationinterop"],"acf":[],"blog_post_summary":"<p>By Jonathan Aneja &nbsp; Hi, my name\u2019s Jonathan and I\u2019m a Program Manager on the VB team, working mainly on LINQ features.&nbsp; One of the things I love about LINQ is it\u2019s not just limited to querying over databases and XML \u2013 you can query over any collection of Objects.&nbsp; For example, let\u2019s say I [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/6813","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=6813"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/6813\/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=6813"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=6813"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=6813"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}