【问题标题】:Using join throws exception that cannot be debugged使用join会抛出无法调试的异常
【发布时间】:2019-07-26 08:54:52
【问题描述】:

我有一个非常简单的代码 sn-p 来测试如何使用“join”将 2 个数据部分连接在一起,如下所示:

class Employee
{
    public string EmpName { get; set; }
    public int DeptId { get; set; }
}
class Department
{
    public int DeptId { get; set; }
    public string DeptName { get; set; }
}
class UseJoin
{
    public static void Test()
    {
        IEnumerable<Employee> employees = new[]
        {
            new Employee{ EmpName="John", DeptId=1 },
            new Employee{ EmpName="Kate", DeptId=2 },
            new Employee{ EmpName="Dave", DeptId=1 },
            new Employee{ EmpName="Dane", DeptId=3 },
            new Employee{ EmpName="Greg", DeptId=4 },
            new Employee{ EmpName="Tony", DeptId=4 },
        };

        IEnumerable<Department> departments = new[]
        {
            new Department{ DeptId = 1, DeptName = "math" },
            new Department{ DeptId = 3, DeptName = "physics" },
            new Department{ DeptId = 4, DeptName = "history" },
            new Department{ DeptId = 5, DeptName = "mandarine" },
        };

        var result = from e in employees
                     join d in departments
                     on e.DeptId equals d.DeptId
                     select new { e.EmpName, d.DeptName };
        Console.WriteLine(result);
    }
}

运行此程序时,控制台窗口会打印如下异常/错误:

System.Linq.Enumerable+<JoinIterator>d__38`4[UseNullable.Employee,UseNullable.Department,System.Int32,<>f__AnonymousType0`2[System.String,System.String]]

我尝试调试,但似乎无法直接调试此声明式 linq,visual studio 一直提示错误消息框。

我在哪里出错以及如何解决?

【问题讨论】:

  • 这不是一个错误,它只是你的一种匿名类型的链接表达式。您可以对其进行迭代并查看内容
  • 如果您想查看结果,请尝试var myList = result.ToList()。在该行之后放置一个断点并查看myList 的内容。这会给出任何例外吗?
  • Id 2 没有为空的部门。修复如下: (d.DeptName == null)? string.Empty : d.DeptName

标签: c# linq join select


【解决方案1】:

正如 cmets 所说,您没有遇到任何错误。以您刚才所做的方式创建查询时,您最终会得到一个 Enumerable,直到您真正想要检索其中的数据时才会对其进行评估。

要强制它获取数据,您可以执行以下操作:

var myList = result.ToList();

这将强制评估 Enumerable,然后在此行之后使用断点,您可以检查 myList 变量并查看其中的值。

关于您的 Console.WriteLine(result); 行 - 这不起作用,因为实际发生的是 WriteLine 实际上会在您的 result 参数上调用 .ToString()ToString 的输出不是查询或列表的内容,而是对象类型的完全限定名称。有关ToString 的更多信息,请访问here

为了打印出查询的内容,您需要像这样遍历它:

foreach (var item in result)
{
    Console.WriteLine(item.EmpName + " - " + item.DeptName);
}

这将强制评估您的 Enumerable 并将您的员工和部门一一打印在新行上。

【讨论】:

    【解决方案2】:

    此代码将迭代并显示Linq 表达式的结果。

    var result = from e in employees
                    join d in departments
                        on e.DeptId equals d.DeptId
                    select new { e.EmpName, d.DeptName };
    
    foreach (var item in result)
    {
        Console.WriteLine(item.EmpName);
        Console.WriteLine(item.DeptName);
    }
    

    您还可以在调试器中展开结果视图并检查值

    【讨论】:

      【解决方案3】:

      您的结果类型为 IEnumerable。您不能直接打印 IEnumerable。您必须循环结果并显式打印对象。

      【讨论】:

        【解决方案4】:

        只需使用 foreach 来输出您的结果。

        foreach(var item in result) {
             Console.WriteLine($"Employee name: {item.EmpName}, Department name: {item.DeptName}");
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-08-18
          • 1970-01-01
          • 2019-08-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多