{"id":5233,"date":"2007-11-06T18:55:00","date_gmt":"2007-11-06T18:55:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2007\/11\/06\/linq-cookbook-recipe-10-pre-compiling-queries-for-performance-doug-rothaus\/"},"modified":"2024-07-05T14:39:05","modified_gmt":"2024-07-05T21:39:05","slug":"linq-cookbook-recipe-10-pre-compiling-queries-for-performance-doug-rothaus","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/linq-cookbook-recipe-10-pre-compiling-queries-for-performance-doug-rothaus\/","title":{"rendered":"LINQ Cookbook, Recipe 10: Pre-compiling Queries for Performance (Doug Rothaus)"},"content":{"rendered":"<p class=\"MsoNormal\"><b><span><font face=\"Calibri\">Ingredients:<\/p>\n<p><\/font><\/span><\/b><\/p>\n<p class=\"MsoListParagraph\"><span><span>&middot;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><font face=\"Calibri\"><span>Visual Studio 2008 (Beta2 or Higher)<\/span><span><\/p>\n<p><\/span><\/font><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\"><b><span>Categories:<\/span><\/b><span> LINQ to SQL<\/p>\n<p><\/span><\/font><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p><font face=\"Calibri\">&nbsp;<\/font><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><b><span><font face=\"Calibri\">Introduction:<\/p>\n<p><\/font><\/span><\/b><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Calibri\">As we add cookbook entries, we will include performance improvement tips where appropriate. Here&rsquo;s a tip that you can use with LINQ to SQL to speed up queries that you will call numerous times: Pre-compiled queries. By pre-compiling a query, you perform the processing to compile the query once, and then skip the compile step every consecutive time that you run the query.<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Calibri\">Pre-compiled queries are created using the <b>Compile<\/b> method of the <b>CompiledQuery<\/b> class in the <b>System.Data.Linq<\/b> namespace. You pass a Lambda expression that contains the variables used by your query (the <b>DataContext<\/b> object, filter variables, and so on) to the <b>Compile<\/b> method to create a compiled query as shown in the following example.<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span>Dim query <span>As<\/span> Func(<span>Of<\/span> NorthwindDataContext, Customer, IQueryable(<span>Of<\/span> Order)) = _<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span>System.Data.Linq.CompiledQuery.Compile( _<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Function<\/span>(database <span>As<\/span> NorthwindDataContext, cust <span>As<\/span> Customer) _<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>From<\/span> order <span>In<\/span> database.Orders _<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Where<\/span> order.Customer <span>Is<\/span> cust)<\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p><\/span>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span><font face=\"Calibri\">The first time the query executes, the query will be compiled and stored in the specified variable. After that, the compiled query is used when the query executes.<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Calibri\">In this recipe, you will create a classic master-detail application using the Northwind sample database. The &ldquo;master&rdquo; list will display the customers from the Northwind database using a LINQ query, and the &ldquo;detail&rdquo; list will display the orders for the selected customer using a pre-compiled query.<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><b><span><font face=\"Calibri\">Instructions:<\/font><\/span><\/b><\/p>\n<p class=\"MsoNormal\"><b><span><font face=\"Calibri\"><\/p>\n<p><\/font><\/span><\/b>&nbsp;<\/p>\n<p class=\"MsoListParagraphCxSpFirst\"><span><span>&middot;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span><font face=\"Calibri\">Create a Win<\/font><\/span><span><font face=\"Calibri\">dows Forms Application with a connection to the Northwind database. Add a LINQ to SQL Classes item named <b>Northwind.dbml<\/b> and drag the Customers and Orders tables to the data classes design surface in the Object Relational Designer. For steps on creating an application that uses the Northwind database, see <\/font><\/span><a href=\"http:\/\/blogs.msdn.com\/vbteam\/archive\/2007\/07\/11\/linq-cookbook-recipe-6-your-first-linq-application-using-northwind.aspx\"><span><font face=\"Calibri\">LINQ Cookbook Recipe 6: Your first LINQ application using Northwind<\/font><\/span><\/a><span><font face=\"Calibri\">.<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoListParagraphCxSpMiddle\"><span><span>&middot;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span><font face=\"Calibri\">From the <b><span>Toolbox<\/span><\/b>, drag a <b>ListBox<\/b> control (to display customer information), a <b>DataGridView<\/b> control (to display order information), and a <b>Label<\/b> control (to display timer information) onto the form. Resize the form and controls as needed.<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoListParagraphCxSpMiddle\"><span><span>&middot;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span><font face=\"Calibri\">Double-click the <b>Form<\/b> to edit the application code.<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoListParagraphCxSpLast\"><span><span>&middot;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span><font face=\"Calibri\">Replace the default <b>Form1 <\/b>class with the following code that defines class-level variables and the <strong>Form1.Load<\/strong> event handler:<\/p>\n<p><\/font><\/span><\/p>\n<p><span><span><font color=\"#0000ff\" size=\"2\"><\/p>\n<p>&nbsp;&nbsp;&nbsp; Imports<\/p>\n<p><\/font><font size=\"2\"> System.Data.Linq<\/font><font color=\"#0000ff\" size=\"2\"><\/p>\n<p>&nbsp;&nbsp;&nbsp; Public<\/p>\n<p><\/font><font size=\"2\"> <\/font><font color=\"#0000ff\" size=\"2\">Class<\/font><font size=\"2\"> Form1<\/p>\n<p class=\"MsoNormal\">\n<p><\/font>&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; Variable to hold the pre-compiled query.<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Private<\/span> orderQuery <span>As<\/span> Func(<span>Of<\/span> NorthwindDataContext, Customer, IQueryable(<span>Of<\/span> Order))<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; LINQ to SQL DataContext object for Northwind.<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Private<\/span> db <span>As<\/span> <span>New<\/span> NorthwindDataContext<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; Timer to show performance difference.<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> queryTimer <span>As<\/span> <span>New<\/span> Stopwatch<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> slowestTime <span>As<\/span> <span>Long<font color=\"#000000\">?<\/font><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> currentTime <span>As<\/span> <span>Long<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Private<\/span> <span>Sub<\/span> Form1_Load() <span>Handles<\/span> <span>MyBase<\/span>.Load<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; Get the list of Customers and bind it to ListBox1.<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>ListBox1.DataSource = <span>From<\/span> cust <span>In<\/span> db.Customers _<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><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><span>Select<\/span> cust _<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><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><span>Order<\/span> <span>By<\/span> cust.CompanyName<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>ListBox1.DisplayMember = <span>&#8220;CompanyName&#8221;<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span><\/span><\/span>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span><span>End Class<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span><\/p>\n<p><\/span><\/span>&nbsp;<\/p>\n<p class=\"MsoListParagraph\"><span><span>&middot;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span><font face=\"Calibri\">After the <b>Form.Load<\/b> event, add the following <\/font><\/span><span>GetOrders<\/span><span><font face=\"Calibri\"> method to retrieve orders for a customer.<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Private<\/span> <span>Function<\/span> GetOrders(<span>ByVal<\/span> selectedCustomer <span>As<\/span> Customer) <span>As<\/span> List(<span>Of<\/span> Order)<\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p><\/span>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; If the query for orders has not been compiled yet, compile it. Otherwise, <\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8216; use the compiled query.<\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p><\/span>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> orderQuery <span>Is<\/span> <span>Nothing<\/span> <span>Then<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>orderQuery = CompiledQuery.Compile( _<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Function<\/span>(database <span>As<\/span> NorthwindDataContext, cust <span>As<\/span> Customer) _<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>From<\/span> order <span>In<\/span> database.Orders _<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Where<\/span> order.Customer <span>Is<\/span> cust)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp; <\/span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span>End<\/span> <span>If<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p><\/span>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; Execute the compiled query by calling the ToList method and <\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8216; return the<\/span><span> <span>results.<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span><\/p>\n<p><\/span><\/span>&nbsp;<\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Return<\/span> orderQuery(db, selectedCustomer).ToList()<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Function<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span><\/p>\n<p><\/span><\/span>&nbsp;<\/p>\n<p class=\"MsoListParagraph\"><span><span>&middot;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span><font face=\"Calibri\">After the <\/font><\/span><span>GetOrders<\/span><span><font face=\"Calibri\"> method, add the following event handler for the <b>ListBox.SelectedIndexChanged<\/b> event. The event handler will pass the current selected customer to the <\/font><\/span><span>GetOrders<\/span><span><font face=\"Calibri\"> method to call the pre-compiled query and retrieve the orders for that customer. Some simple timer code is added to show the difference between the first time the query executes, and the current execution time.<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Private<\/span> <span>Sub<\/span> ListBox1_SelectedIndexChanged() <span>Handles<\/span> ListBox1.SelectedIndexChanged<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>queryTimer.Reset()<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>queryTimer.Start()<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; If a customer has been selected, get the list of orders for the customer<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ingredients: &middot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Visual Studio 2008 (Beta2 or Higher) &nbsp; Categories: LINQ to SQL &nbsp; Introduction: As we add cookbook entries, we will include performance improvement tips where appropriate. Here&rsquo;s a tip that you can use with LINQ to SQL to speed up queries that you will call numerous times: Pre-compiled queries. By pre-compiling a query, [&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":[59,93,94,117,166],"class_list":["post-5233","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-featured","category-visual-basic","tag-doug-rothaus","tag-linq-cookbook","tag-linqvb9","tag-orcas","tag-vb2008"],"acf":[],"blog_post_summary":"<p>Ingredients: &middot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Visual Studio 2008 (Beta2 or Higher) &nbsp; Categories: LINQ to SQL &nbsp; Introduction: As we add cookbook entries, we will include performance improvement tips where appropriate. Here&rsquo;s a tip that you can use with LINQ to SQL to speed up queries that you will call numerous times: Pre-compiled queries. By pre-compiling a query, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/5233","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=5233"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/5233\/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=5233"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=5233"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=5233"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}