嗨,我正在通过MS 101 linq示例进行编码。

“ JoinOperators”让我很难过,因为我试图将查询表达式重构为lambda语法,反之亦然。

无论如何,在示例105上,我看到以下查询表达式:

var supplierCusts =
    from sup in suppliers
    join cust in customers on sup.Country equals cust.Country into cs
    from c in cs.DefaultIfEmpty()  // DefaultIfEmpty preserves left-hand elements that have no matches on the right side
    orderby sup.SupplierName
    select new
    {
        Country = sup.Country,
        CompanyName = c == null ? "(No customers)" : c.CompanyName,
        SupplierName = sup.SupplierName
    };


我尝试通过以下方式将其作为lambda实现:

// something is not right here because the result keeps a lot of "Join By" stuff in the output below
var supplierCusts =
    suppliers.GroupJoin(customers, s => s.Country, c => c.Country, (s, c) => new { Customers = customers, Suppliers = suppliers })
        .OrderBy(i => i.Suppliers)    // can't reference the "name" field here?
        .SelectMany(x => x.Customers.DefaultIfEmpty(), (x, p) =>    // does the DefaultIfEmpty go here?
            new
            {
                Country = p.Country,
                CompanyName = x == null ? "(No customers)" : p.CompanyName,
                SupplierName = p    // not right: JoinOperators.Program+Customer ... how do I get to supplier level?
            });


由于某种原因,我无法以这种方式访问​​供应商级别的信息。当我与供应商交换客户时,我无法访问客户级别的信息。

是否存在SelectMany的一些重载,让我从两个对象的字段级撤消?

另外,我不明白为什么GroupJoin似乎返回一个具有2个集合(供应商和客户)的对象。难道不应该以某种方式加入他们的行列吗?

我想我不了解GroupJoin的工作方式。

最佳答案

组连接中的结果选择器错误,这是问题开始的地方。这是固定查询:

var supplierCusts =
   suppliers
     .GroupJoin(customers,
                sup => sup.Country,
                cust => cust.Country,
                (sup, cs) => new { sup, cs })
     .OrderBy(x => x.sup.Name)
     .SelectMany(x => x.cs.DefaultIfEmpty(), (x, c) =>
        new
        {
            Country = x.sup.Country,
            CompanyName = c == null ? "(No customers)" : c.CompanyName,
            SupplierName = x.sup.Name
        });

10-04 16:19