5

我们在我们的系统中非常广泛地使用 LINQ。特别是 LINQ-to-objects。因此,在某些地方,我们最终会在内存中使用一些巨大的表达式构建 LINQ 查询。当表达式中有一些错误时,问题就来了。所以我们得到 NullReferenceException 并且堆栈跟踪导致我们无处可去(到 [轻量级函数])。异常是在 LINQ 生成的动态方法中引发的。

有没有简单的方法来调试这种动态方法?还是我必须牺牲自己来学习 WinDBG?:-)

4

3 回答 3

3

如果您正在构建自己的表达式并编译它们,或者使用 AsQueryable,那么可以;LINQ 生成的方法将是一个非常痛苦的调试。

您可以通过使用实际方法的小片段来节省一些痛苦- 至少有用的东西会显示在堆栈跟踪中......

另一个考虑因素是:与其拥有一个巨大的表达式,如果您可以将事物以菊花链方式连接得更多,您可能会(从堆栈跟踪)知道它失败的地方。缺点是性能 - Where(foo).Where(bar) 是两个委托调用,where-as Where(foo && bar) 可以是一个。

一种选择可能是换入扩展方法的调试版本;不幸的是,这有点不方便,因为IQueryable<T>Queryable位于同一个命名空间中......不过,这很有效......

先输出:

>Where: x => ((x % 2) = 0)
<Where: x => ((x % 2) = 0)
>Count
'WindowsFormsApplication2.vshost.exe' (Managed): Loaded 'Anonymously Hosted DynamicMethods Assembly'
<Count

代码:

using System;
using System.Diagnostics;
using System.Linq.Expressions;

namespace Demo
{
    using DebugLinq;
    static class Program
    {
        static void Main()
        {
            var data = System.Linq.Queryable.AsQueryable(new[] { 1, 2, 3, 4, 5 });
            data.Where(x => x % 2 == 0).Count(); 
        }
    }
}
namespace DebugLinq
{
    public static class DebugQueryable
    {
        public static int Count<T>(this System.Linq.IQueryable<T> source)
        {
            return Wrap(() => System.Linq.Queryable.Count(source), "Count");
        }

        public static System.Linq.IQueryable<T> Where<T>(this System.Linq.IQueryable<T> source, Expression<Func<T, bool>> predicate)
        {
            return Wrap(() => System.Linq.Queryable.Where(source, predicate), "Where: " + predicate);
        }
        static TResult Wrap<TResult>(Func<TResult> func, string caption)
        {
            Debug.WriteLine(">" + caption);
            try
            {
                TResult result = func();
                Debug.WriteLine("<" + caption);
                return result;
            }
            catch
            {
                Debug.WriteLine("!" + caption);
                throw;
            }
        }
    }
}
于 2008-10-29T08:38:05.987 回答
1

如果您使用的是 LINQ to Objects,我不希望看到创建动态方法。我希望他们使用 LINQ to SQL 等。你能举一个你看到这个的例子吗?

当谈到 LINQ 时,我真的没有任何好的调试技巧,但我很确定 MS 知道这是一个痛点。我可以建议你试试VS2010 CTP看看是否更好?诚然,更多是为了改进 VS,而不是为了解决你眼前的问题。

于 2008-10-29T08:25:00.397 回答
0

看看最初由Haibo Luo开发并由Roy Osherove进一步开发的动态方法的调试可视化器

于 2009-05-20T23:03:31.867 回答