左外连接错误

时间:2013-04-03 20:33:44

标签: c# linq

我试图让这个左外连接工作,但我似乎遇到了一些问题。我从MSDN left join article获取了示例代码。这个例子是LINQ语法,但我想扩展方法语法,所以我也引用了这个SO问题。

Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };

Pet barley = new Pet { Name = "Barley", Owner = terry };
Pet boots = new Pet { Name = "Boots", Owner = terry };
Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
Pet bluemoon = new Pet { Name = "Blue Moon", Owner = terry };
Pet daisy = new Pet { Name = "Daisy", Owner = magnus };

// Create two lists.
List<Person> people = new List<Person> { magnus, terry, charlotte, arlene };
List<Pet> pets = new List<Pet> { barley, boots, whiskers, bluemoon, daisy };

var query = people
            .GroupJoin(pets,
            p1 => p1.FirstName,
            p2 => p2.Owner.FirstName,
            (p1, p2) => new {p1,p2})
            .SelectMany(x => x.p2.DefaultIfEmpty(),
             (x, y) => new { FirstName = x.p1.FirstName, PetName = y.Name });

        foreach (var v in query)
        {
            Console.WriteLine("{0,-15}{1}", v.FirstName + ":", v.PetName);
        }

我的查询与我引用的代码基本相同,但我收到此错误:

NullReferenceException
Object reference not set to an instance of an object. 

这应该非常简单。我做错了什么?

1 个答案:

答案 0 :(得分:1)

您缺少示例查询的那部分:

PetName = (subpet == null ? String.Empty : subpet.Name)

在您的查询中,它只是PetName = y.Name,因此,只要pets列表中没有相应的行,您就会获得NullReferrenceException,因为ynull

应该是:

var query = people
            .GroupJoin(pets,
            p1 => p1.FirstName,
            p2 => p2.Owner.FirstName,
            (p1, p2) => new { p1, p2 })
            .SelectMany(x => x.p2.DefaultIfEmpty(),
                (x, y) => new { FirstName = x.p1.FirstName, PetName = (y == null ? String.Empty : y.Name) });

或者您可以使用DefaultIdEmpty(TSource)方法重载:

var def = new Pet { Name = string.Empty };

var query = people
            .GroupJoin(pets,
            p1 => p1.FirstName,
            p2 => p2.Owner.FirstName,
            (p1, p2) => new { p1, p2 })
            .SelectMany(x => x.p2.DefaultIfEmpty(def),
                (x, y) => new { FirstName = x.p1.FirstName, PetName = y.Name });