title: How to optimize this LINQ query for Visual Studio?
body: <p>I have this one gigantic complex LINQ to SQL query that I need to optimize somehow, because the background C# compiler completely hogs the CPU and I can't type or edit my <code>.cs</code> file normally in Visual Studio 2010 (every letter, especially if IntelliSense wants to pop up, lags horribly).</p>
  
  <p>The culprit is this:</p>
  
  <pre><code>var custFVC = 
      (from cfvc in customer.CustomerFrameVariationCategories
      let lastValue = cfvc.CustomerFrameVariationCategoryValueChanges.Where(cfvcvc =&gt; cfvcvc.ChangeDateTime &lt;= this.SelectedDateTime).OrderByDescending(cfvcvc2 =&gt; cfvcvc2.ChangeDateTime).FirstOrDefault() ?? new CustomerFrameVariationCategoryValueChange()
      let lastValue2 = cfvc.FrameVariationCategory.FrameVariation.Frame.FrameValueChanges.Where(fvc =&gt; fvc.ChangeDateTime &lt;= this.SelectedDateTime).OrderByDescending(fvc2 =&gt; fvc2.ChangeDateTime).FirstOrDefault() ?? new FrameValueChange()
      let lastValue3 = cfvc.FrameVariationCategory.FrameVariationCategoryValueChanges.Where(fvcvc =&gt; fvcvc.ChangeDateTime &lt;= this.SelectedDateTime).OrderByDescending(fvcvc2 =&gt; fvcvc2.ChangeDateTime).FirstOrDefault() ?? new FrameVariationCategoryValueChange()
      let lastValue4 = cfvc.FrameVariationCategory.FrameVariation.FrameVariationModules.Any(fvm =&gt; (fvm.FrameModule.FrameModuleValueChanges.Where(fmvc =&gt; fmvc.ChangeDateTime &lt;= this.SelectedDateTime).OrderByDescending(fmvc2 =&gt; fmvc2.ChangeDateTime).FirstOrDefault() ?? new FrameModuleValueChange()).IsActive == false)
      where lastValue.IsActive == true
      orderby cfvc.FrameVariationCategory.FrameVariation.Frame.Name, cfvc.FrameVariationCategory.Category.Name, cfvc.FrameVariationCategory.FrameVariation.Name
      select new
      {
         cfvc.Id,
         cfvc.FrameVariationCategory,
         lastValue.CoverCoefficient,
         lastValue.NeiserNet,
         PlywoodName = lastValue2.Plywood.Name,
         FrameIsActive = lastValue2.IsActive,
         OwnCost = cfvc.FrameVariationCategory.FrameVariation.FrameVariationModules.Sum(fvm =&gt; // sum all frame variation modules
            (lastValue4 ? 0 : fvm.FrameModule.FrameModuleValueChanges.Where(fmvc =&gt; fmvc.ChangeDateTime &lt;= this.SelectedDateTime) // if module not active then 0
            .OrderByDescending(fmvc2 =&gt; fmvc2.ChangeDateTime).FirstOrDefault().Porolone) + // otherwise get Porolone
             fvm.FrameModule.FrameModuleComponents.Sum(fmc =&gt; // add to Porolone sum of all module components
             (fmc.Article.ArticleDetails.Any() ? fmc.Article.ArticleDetails.Sum(ad =&gt; // if any article details then use A*L*W*T instead of Amount
             WindowExcel.MultiplyArticleDetailValues(ad.ArticleDetailValueChanges.Where(advc =&gt; advc.ChangeDateTime &lt;= this.SelectedDateTime)
            .OrderByDescending(advc2 =&gt; advc2.ChangeDateTime).FirstOrDefault() ?? new ArticleDetailValueChange())) : 
             WindowExcel.GetModuleComponentAmount(fmc.FrameModuleComponentValueChanges.Where(fmcvc =&gt; fmcvc.ChangeDateTime &lt;= this.SelectedDateTime) // no details = get amount
               .OrderByDescending(fmcvc2 =&gt; fmcvc2.ChangeDateTime).FirstOrDefault() ?? new FrameModuleComponentValueChange())) * // times article values
             WindowExcel.MultiplyArticleValues(fmc.Article.ArticleValueChanges.Where(avc =&gt; avc.ChangeDateTime &lt;= this.SelectedDateTime)
             .OrderByDescending(avc2 =&gt; avc2.ChangeDateTime).FirstOrDefault() ?? new ArticleValueChange()))),
         Cubes = cfvc.FrameVariationCategory.FrameVariation.FrameVariationModules.Sum(fvm =&gt; (fvm.FrameModule.FrameModuleValueChanges.Where(fmvc =&gt; fmvc.ChangeDateTime &lt;= this.SelectedDateTime &amp;&amp; fmvc.IsActive == true).OrderByDescending(fmvc2 =&gt; fmvc2.ChangeDateTime).FirstOrDefault() ?? new FrameModuleValueChange()).Cubes),
         lastValue3.CoverNet,
         lastValue3.CoverGarbage,
         lastValue3.CoverGross,
         lastValue3.CoverPrice,
         lastValue3.BackgroundNet,
         lastValue3.BackgroundGarbage,
         lastValue3.BackgroundGross,
         lastValue3.BackgroundPrice,
         FVCIsActive = lastValue3.IsActive,
         FrameModuleAnyNonActive = lastValue4
      }).ToList();
  </code></pre>
  
  <p>The biggest problem here is <code>OwnCost</code>, everything up to and after that Visual Studio can handle. I don't want to turn off background compiling (a feature that checks for compile time errors before actually compiling), I don't want to create a stored procedure. I can't off this code into a separate class/method, because the LINQ DataContext can't be passed around (as far as I know - also take into consideration that the context variable is inside a <code>using</code> statement).</p>
  
  <p>The only vague idea that I have, is some sort of an extension method, or a method that returns a LINQ query or something like that. Because I don't know what exactly it is that I can do here to rectify the problem, I don't know how to formulate the wording, thus I can't google it...</p>
  
  <p>How can I move (or optimize) <code>OwnCost</code> or the entire query out of the current <code>.cs</code> file, or perhaps split it into a method within the same file (might help the background compiler), or "something"...?</p>