调试LINQ查询

问题描述 投票:17回答:6

最近,我们已经在LINQ上做了很多工作,主要是在LINQ to Objects的意义上。不幸的是,我们的某些查询可能会有些复杂,尤其是当它们开始涉及多个序列的组合时。当您收到开始看起来像的查询时,可能很难确切地知道发生了什么:

IEnumerable<LongType> myCompanies =       relevantBusiness.Children_Companies
            .Select(ca => ca.PR_ContractItemId)
            .Distinct()
            .Select(id => new ContractedItem(id))
            .Select(ci => ci.PR_ContractPcrId)
            .Distinct()
            .Select(id => new ContractedProdCompReg(id))
            .Select(cpcr => cpcr.PR_CompanyId)
            .Distinct();

var currentNewItems = myCompanies 
                .Where(currentCompanyId => !currentLic.Children_Appointments.Select(app => app.PR_CompanyId).Any(item => item == currentCompanyId))
                .Select(currentId => new AppointmentStub(currentLic, currentId))
                .Where(currentStub=>!existingItems.Any(existing=>existing.IsMatch(currentStub)));


Items = existingItems.Union(newItems).ToList();

等,等等...

即使您进行调试,也很难分辨谁在何时何地做什么。缺少在序列上随意调用“ ToList”以使我可以更轻松地检查事情的方法,对于调试“复杂” LINQ的人是否有任何好的建议?

c# linq debugging
6个回答
15
投票

这样的查询似乎向我表明,您在选择合适的数据结构方面做得不好,或者在封装和分离任务方面做得不好。我建议您看看并分解。

但是,通常,如果我要调试明显不正确的LINQ查询,我会将其分解为子查询,并在调试器中一次检查结果。


14
投票

我知道我的回答“有点”晚了,但是我必须分享这个:

刚刚发现了LinqPad,这是惊人的(更不用说免费了)。不知道我已经写了这么长时间的Linq,却不知道这个工具。

据我了解,这是O'Reilly "C# 3.0 in a Nutshell""C# 4.0 in a Nutshell"的作者的工作。


8
投票

[当我最近环顾​​四周以寻找相同问题的答案时,我在这里和那里发现了一些有趣的提示,但是并没有真正的内在叙述来挖掘问题的答案。所以我自己写了一个,它刚发布在Simple-Talk.com(LINQ Secrets Revealed: Chaining and Debugging)上。您可能需要注册才能阅读该文章(最近几天该网站似乎发生了一些变化),因此,这里是本文的重点:

((1)在LINQPad中:使用其非凡的Dump()方法。您可以在LINQ链中的一个或多个点上注入此数据,以一种惊人的干净清晰的方式查看数据。

((2)在Visual Studio中:在LINQ链的中间嵌入nop语句,以便您可以设置断点。请注意,return语句必须在其单独的行上才能在Visual Studio中设置断点。 (由于此技巧,Eric White的博客条目Debugging LINQ Queries。)

.Select(z =>
{return z;}
)

((3)在Visual Studio中:注入对我在本文中介绍的Dump()扩展方法的调用以允许记录。我在他的信息丰富的文章LINQ to Objects – Debugging中从Bart De Smet的Watch()方法开始,并添加了一些标签和颜色以增强可视化效果,尽管与LINQPad的Dump输出相比仍然显得苍白。

((4)最后,(是的,我对LINQPad的Dump方法很着迷!)使用Robert Ivanc的LINQPad Visualizer外接程序将LINQPad的可视化功能带入Visual Studio。这不是一个完美的解决方案(尚不支持VS2010,要求类可序列化,存在一些渲染问题),但它非常有用。

2016.12.01更新

刚刚在Simple-Talk.com上发布是上述文章的后继:LINQ Debugging and Visualization。本文全面介绍了Visual Studio 2015的OzCode扩展的新LINQ调试功能。OzCode最终使LINQ调试变得简单而强大。 (而且,不,我为OzCode做not工作:-)。


4
投票

我所知道的没有内置工具。最好的办法是将查询分为多个子查询,并在调试时评估这些子查询。一个好的第三方工具是LINQPad


2
投票

马苹果!

Resharper(我喜欢)建议我更改此内容>>

foreach (BomObservation initialObservation in initialObservations)
{
    if(initialObservation.IsValid() && !initialObservation.IsStationOnly)
        mappableObservations.Add(initialObservation);
}

至此

initialObservations.Where(observation => observation.IsValid() && !observation.IsStationOnly).ToList();

是的,它既性感又时尚,但要逐步调试它吗?你就是做不到。我将为此再回到foreach。

我也喜欢LinqPad,我确实认为Linq在“一圈把它们全部统治”方面非常棒,但在这种情况下,我会失去一些东西。


0
投票

我知道这是一个老问题,但是我发现其他解决方案可能对某人有用。在调试LINQ查询时,我一直在同一个问题上挣扎。有两种调试它们的好方法。

© www.soinside.com 2019 - 2024. All rights reserved.