C# 如何为Visual Studio优化此LINQ查询?

C# 如何为Visual Studio优化此LINQ查询?,c#,.net,wpf,linq,performance,C#,.net,Wpf,Linq,Performance,我有一个庞大复杂的LINQ到SQL查询,我需要以某种方式进行优化,因为后台C#编译器完全占用了CPU,我无法在Visual Studio 2010中正常键入或编辑我的.cs文件(每个字母,尤其是如果IntelliSense想要弹出,都会严重滞后) 罪魁祸首是: var custFVC = (from cfvc in customer.CustomerFrameVariationCategories let lastValue = cfvc.CustomerFrameVariat

我有一个庞大复杂的LINQ到SQL查询,我需要以某种方式进行优化,因为后台C#编译器完全占用了CPU,我无法在Visual Studio 2010中正常键入或编辑我的
.cs
文件(每个字母,尤其是如果IntelliSense想要弹出,都会严重滞后)

罪魁祸首是:

var custFVC = 
    (from cfvc in customer.CustomerFrameVariationCategories
    let lastValue = cfvc.CustomerFrameVariationCategoryValueChanges.Where(cfvcvc => cfvcvc.ChangeDateTime <= this.SelectedDateTime).OrderByDescending(cfvcvc2 => cfvcvc2.ChangeDateTime).FirstOrDefault() ?? new CustomerFrameVariationCategoryValueChange()
    let lastValue2 = cfvc.FrameVariationCategory.FrameVariation.Frame.FrameValueChanges.Where(fvc => fvc.ChangeDateTime <= this.SelectedDateTime).OrderByDescending(fvc2 => fvc2.ChangeDateTime).FirstOrDefault() ?? new FrameValueChange()
    let lastValue3 = cfvc.FrameVariationCategory.FrameVariationCategoryValueChanges.Where(fvcvc => fvcvc.ChangeDateTime <= this.SelectedDateTime).OrderByDescending(fvcvc2 => fvcvc2.ChangeDateTime).FirstOrDefault() ?? new FrameVariationCategoryValueChange()
    let lastValue4 = cfvc.FrameVariationCategory.FrameVariation.FrameVariationModules.Any(fvm => (fvm.FrameModule.FrameModuleValueChanges.Where(fmvc => fmvc.ChangeDateTime <= this.SelectedDateTime).OrderByDescending(fmvc2 => 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 => // sum all frame variation modules
          (lastValue4 ? 0 : fvm.FrameModule.FrameModuleValueChanges.Where(fmvc => fmvc.ChangeDateTime <= this.SelectedDateTime) // if module not active then 0
          .OrderByDescending(fmvc2 => fmvc2.ChangeDateTime).FirstOrDefault().Porolone) + // otherwise get Porolone
           fvm.FrameModule.FrameModuleComponents.Sum(fmc => // add to Porolone sum of all module components
           (fmc.Article.ArticleDetails.Any() ? fmc.Article.ArticleDetails.Sum(ad => // if any article details then use A*L*W*T instead of Amount
           WindowExcel.MultiplyArticleDetailValues(ad.ArticleDetailValueChanges.Where(advc => advc.ChangeDateTime <= this.SelectedDateTime)
          .OrderByDescending(advc2 => advc2.ChangeDateTime).FirstOrDefault() ?? new ArticleDetailValueChange())) : 
           WindowExcel.GetModuleComponentAmount(fmc.FrameModuleComponentValueChanges.Where(fmcvc => fmcvc.ChangeDateTime <= this.SelectedDateTime) // no details = get amount
             .OrderByDescending(fmcvc2 => fmcvc2.ChangeDateTime).FirstOrDefault() ?? new FrameModuleComponentValueChange())) * // times article values
           WindowExcel.MultiplyArticleValues(fmc.Article.ArticleValueChanges.Where(avc => avc.ChangeDateTime <= this.SelectedDateTime)
           .OrderByDescending(avc2 => avc2.ChangeDateTime).FirstOrDefault() ?? new ArticleValueChange()))),
       Cubes = cfvc.FrameVariationCategory.FrameVariation.FrameVariationModules.Sum(fvm => (fvm.FrameModule.FrameModuleValueChanges.Where(fmvc => fmvc.ChangeDateTime <= this.SelectedDateTime && fmvc.IsActive == true).OrderByDescending(fmvc2 => 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();
var custFVC=
(来自customer.CustomerFrameVariationCategories中的cfvc)
让lastValue=cfvc.CustomerFrameVariationCategoryValueChanges.Where(cfvcvc=>cfvcvc.ChangeDateTime CFVC2.ChangeDateTime).FirstOrDefault()??新建CustomerFrameVariationCategoryValueChange()
让lastValue2=cfvc.FrameVariationCategory.FrameVariation.Frame.FrameValueChanges.Where(fvc=>fvc.ChangeDateTime fvc2.ChangeDateTime).FirstOrDefault()
让lastValue3=cfvc.FrameVariationCategory.FrameVariationCategoryValueChanges.Where(fvcvc=>fvcvc.ChangeDateTime FVCC2.ChangeDateTime).FirstOrDefault()??新的FrameVariationCategoryValueChange()
让lastValue4=cfvc.FrameVariationCategory.FrameVariation.FrameVariationModules.Any(fvm=>(fvm.FrameModule.FrameModuleValueChanges.Where(fmvc=>fmvc.ChangeDateTime fmvc2.ChangeDateTime)。FirstOrDefault()?new FrameModuleValueChange())。IsActive==false)
其中lastValue.IsActive==true
orderby cfvc.FrameVariationCategory.FrameVariation.Frame.Name、cfvc.FrameVariationCategory.Category.Name、cfvc.FrameVariationCategory.FrameVariation.Name
选择新的
{
cfvc.Id,
cfvc.FrameVariationCategory,
lastValue.Covercovercient,
lastValue.NeiserNet,
PlywoodName=lastValue2.collate.Name,
FrameIsActive=lastValue2.IsActive,
OwnCost=cfvc.FrameVariationCategory.FrameVariation.FrameVariationModules.Sum(fvm=>//对所有帧变量模块求和
(lastValue4?0:fvm.FrameModule.FrameModuleValueChanges.Where(fmvc=>fmvc.ChangeDateTime fmvc2.ChangeDateTime).FirstOrDefault().Porolone)+//否则获取Porolone
fvm.FrameModule.FrameModuleComponents.Sum(fmc=>//添加到所有模块组件的Porolone和中
(fmc.Article.ArticleDetails.Any()?fmc.Article.ArticleDetails.Sum(ad=>//如果有任何文章详细信息,则使用*L*W*T代替金额
WindowExcel.MultiplyArticleDetailValueChanges(ad.ArticleDetailValueChanges.Where(advc=>advc.ChangeDateTime advc2.ChangeDateTime).FirstOrDefault()??new-ArticleDetailValueChange()):
WindowExcel.GetModuleComponentAmount(fmc.FrameModuleComponentValueChanges.Where(fmcvc=>fmcvc.ChangeDateTime fmcvc2.ChangeDateTime).FirstOrDefault()?new FrameModuleComponentValueChange())*//次文章值
WindowExcel.MultiplyArticleValues(fmc.Article.ArticleValueChanges.Where(avc=>avc.ChangeDateTime avc2.ChangeDateTime).FirstOrDefault()??new ArticleValueChange()),
多维数据集=cfvc.FrameVariationCategory.FrameVariation.FrameVariationModules.Sum(fvm=>(fvm.FrameModule.FrameModuleValueChanges.Where(fmvc=>fmvc.ChangeDateTime fmvc2.ChangeDateTime).FirstOrDefault()??new FrameModuleValueChange()).Cubes),
lastValue3.CoverNet,
lastValue3.CoverGarage,
lastValue3.CoverGross,
lastValue3.CoverPrice,
lastValue3.BackgroundNet,
lastValue3.background垃圾,
lastValue3.BackgroundGross,
lastValue3.背景价格,
FVCIsActive=lastValue3.IsActive,
FrameModuleAnyNonActive=lastValue4
}).ToList();
这里最大的问题是
OwnCost
,VisualStudio之前和之后的一切都可以处理。我不想关闭后台编译(在实际编译之前检查编译时错误的功能),我不想创建存储过程。我无法将此代码分离到单独的类/方法中,因为无法传递LINQ DataContext(据我所知,还需要考虑上下文变量位于
using
语句中)

我唯一模糊的想法是某种扩展方法,或返回LINQ查询的方法或类似的方法。因为我不知道我能在这里做些什么来纠正这个问题,我不知道如何制定措辞,因此我不能谷歌它


如何将
OwnCost
或整个查询从当前
.cs
文件中移出(或优化),或者将其拆分为同一文件中的一个方法(可能有助于后台编译器)或“其他内容”…?

不用将LINQ写入SQL,您可以为此编写一个存储过程来完成所有这些事情。

我对C编译器中的代价没有任何内在的了解。然而,当我查看您的查询时,有两件事会跳出来

  • let
    绑定的数量和复杂性
  • select子句中
    OwnCost
    成员的初始值设定项的复杂性

  • 我能给出的最好建议是尝试将查询分解,以便将这些查询分解成单独的语句,希望这能减轻编译器的压力。

    将其分解。这是VS试图处理的一个大型表达式树。您可以将其分解,以便在LINQ to对象中发生一些SELECT子句转换。这将使后台编译器更容易处理。只需获得:

    var custFVC = (from cfvc in customer.CustomerFrameVariationCategories
                   let lastValue = cfvc.CustomerFrameVariationCategoryValueChanges.Where(cfvcvc => cfvcvc.ChangeDateTime <= this.SelectedDateTime).OrderByDescending(cfvcvc2 => cfvcvc2.ChangeDateTime).FirstOrDefault() ?? new CustomerFrameVariationCategoryValueChange()
                   let lastValue2 = cfvc.FrameVariationCategory.FrameVariation.Frame.FrameValueChanges.Where(fvc => fvc.ChangeDateTime <= this.SelectedDateTime).OrderByDescending(fvc2 => fvc2.ChangeDateTime).FirstOrDefault() ?? new FrameValueChange()
                   let lastValue3 = cfvc.FrameVariationCategory.FrameVariationCategoryValueChanges.Where(fvcvc => fvcvc.ChangeDateTime <= this.SelectedDateTime).OrderByDescending(fvcvc2 => fvcvc2.ChangeDateTime).FirstOrDefault() ?? new FrameVariationCategoryValueChange()
                   let lastValue4 = cfvc.FrameVariationCategory.FrameVariation.FrameVariationModules.Any(fvm => (fvm.FrameModule.FrameModuleValueChanges.Where(fmvc => fmvc.ChangeDateTime <= this.SelectedDateTime).OrderByDescending(fmvc2 => 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, lastValue, lastValue1, lastValue2, lastValue3}).ToList();
    
    var custFVC=(来自customer.CustomerFrameVariationCategories中的cfvc
    让lastValue=cfvc.CustomerFrameVariationCategoryValueChanges.Where(cfvcvc=>cfvcvc.ChangeDateTime CFVC2.ChangeDateTime).FirstOrDefault()??新建CustomerFrameVariationCategoryValueChange()
    让lastValue2=cfvc.FrameVariationCategory.FrameVariation.Frame.FrameValueChanges.Where(fvc=>fvc.ChangeDateTime fvc2.ChangeDateTime).FirstOrDefault()
    设lastValue3=cfvc.FrameVariationCategory.FrameVariati
    
    OwnCost = cfvc.Select(CalculateOwnCost)
    
    public decimal CalculateOwnCost(CustomerFrameVariationCategory cvfc)
    {
       return cfvc.FrameVariationCategory.FrameVariation.FrameVariationModules.Sum(fvm => // sum all frame variation modules
                     (lastValue4 ? 0 : fvm.FrameModule.FrameModuleValueChanges.Where(fmvc => fmvc.ChangeDateTime <= this.SelectedDateTime) // if module not active then 0
                     .OrderByDescending(fmvc2 => fmvc2.ChangeDateTime).FirstOrDefault().Porolone) + // otherwise get Porolone
                      fvm.FrameModule.FrameModuleComponents.Sum(fmc => // add to Porolone sum of all module components
                      (fmc.Article.ArticleDetails.Any() ? fmc.Article.ArticleDetails.Sum(ad => // if any article details then use A*L*W*T instead of Amount
                      WindowExcel.MultiplyArticleDetailValues(ad.ArticleDetailValueChanges.Where(advc => advc.ChangeDateTime <= this.SelectedDateTime)
                     .OrderByDescending(advc2 => advc2.ChangeDateTime).FirstOrDefault() ?? new ArticleDetailValueChange())) : 
                      WindowExcel.GetModuleComponentAmount(fmc.FrameModuleComponentValueChanges.Where(fmcvc => fmcvc.ChangeDateTime <= this.SelectedDateTime) // no details = get amount
                     .OrderByDescending(fmcvc2 => fmcvc2.ChangeDateTime).FirstOrDefault() ?? new FrameModuleComponentValueChange())) * // times article values
                      WindowExcel.MultiplyArticleValues(fmc.Article.ArticleValueChanges.Where(avc => avc.ChangeDateTime <= this.SelectedDateTime)
                      .OrderByDescending(avc2 => avc2.ChangeDateTime).FirstOrDefault() ?? new ArticleValueChange()))),
                  Cubes = cfvc.FrameVariationCategory.FrameVariation.FrameVariationModules.Sum(fvm => (fvm.FrameModule.FrameModuleValueChanges.Where(fmvc => fmvc.ChangeDateTime <= this.SelectedDateTime && fmvc.IsActive == true).OrderByDescending(fmvc2 => fmvc2.ChangeDateTime).FirstOrDefault() ?? new FrameModuleValueChange()).Cubes)
    }
    
    OwnCost = cfvc.Select(x => CalculateOwnCost(x))
    
    public partial class WindowExcel
    {
        private static decimal GetOwnCost(CustomerFrameVariationCategory cfvc, bool frameModuleAnyNonActive, DateTime selectedDateTime)
        {
            return cfvc.FrameVariationCategory.FrameVariation.FrameVariationModules.Sum(fvm => // sum all frame variation modules
                (frameModuleAnyNonActive ? 0 : fvm.FrameModule.FrameModuleValueChanges.Where(fmvc => fmvc.ChangeDateTime <= selectedDateTime) // if module not active then 0
                .OrderByDescending(fmvc2 => fmvc2.ChangeDateTime).FirstOrDefault().Porolone) + // otherwise get Porolone
                fvm.FrameModule.FrameModuleComponents.Sum(fmc => // add to Porolone sum of all module components
                    (fmc.Article.ArticleDetails.Any() ? fmc.Article.ArticleDetails.Sum(ad => // if any article details then use A*L*W*T instead of Amount
                        WindowExcel.MultiplyArticleDetailValues(ad.ArticleDetailValueChanges.Where(advc => advc.ChangeDateTime <= selectedDateTime)
                        .OrderByDescending(advc2 => advc2.ChangeDateTime).FirstOrDefault() ?? new ArticleDetailValueChange())) :
                        WindowExcel.GetModuleComponentAmount(fmc.FrameModuleComponentValueChanges.Where(fmcvc => fmcvc.ChangeDateTime <= selectedDateTime) // no details = get amount
                        .OrderByDescending(fmcvc2 => fmcvc2.ChangeDateTime).FirstOrDefault() ?? new FrameModuleComponentValueChange())) * // times article values
                        WindowExcel.MultiplyArticleValues(fmc.Article.ArticleValueChanges.Where(avc => avc.ChangeDateTime <= selectedDateTime)
                        .OrderByDescending(avc2 => avc2.ChangeDateTime).FirstOrDefault() ?? new ArticleValueChange())));
        }
    }
    
    OwnCost = WindowExcel.GetOwnCost(cfvc, lastValue4, this.SelectedDateTime)