2

我正在阅读http://msdn.microsoft.com/en-us/library/vstudio/bb397895.aspx的左外连接

    class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

    class Pet
    {
        public string Name { get; set; }
        public Person Owner { get; set; }
    }

    public static void LeftOuterJoinExample()
    {
        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 = from person in people
                    join pet in pets on person equals pet.Owner into gj
                    from subpet in gj.DefaultIfEmpty()
                    select new { person.FirstName, PetName = (subpet == null ? String.Empty : subpet.Name) };

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

    // This code produces the following output: 
    // 
    // Magnus:         Daisy 
    // Terry:          Barley 
    // Terry:          Boots 
    // Terry:          Blue Moon 
    // Charlotte:      Whiskers 
    // Arlene:

我想学习外连接,所以我稍微调整了一下

    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" };
    **Person Momo = new Person { FirstName = "Momo", LastName = "Shawn" };**

    **Pet kaw = new Pet { Name = "Kaw", Owner = Momo };**
    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, **kaw** };

    var query = from pet in pets
                join person in people on pet.Owner equals person into gj
                from subpet in gj.DefaultIfEmpty()
                select new { name = (pet.Owner == null ? "unknown": person.FirstName) , PetName = (subpet == null ? String.Empty : subpet.Name) };

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

Intellisense 不显示。为什么?我一直认为您可以在连接中交换左侧和右侧。但显然,你不能。

是否有任何文件可以解释这一点?

4

2 回答 2

1

Intellisense 不显示人。为什么?

因为它只在join ... into子句的范围内。person但是无论如何,您都在选择每个值,如下所示:

from subpet in gj.DefaultIfEmpty()

...所以只需使用subpet而不是person. 哎呀,如果你愿意,你甚至可以调用范围变量person

var query = from pet in pets
            join person in people on pet.Owner equals person into gj
            from person in gj.DefaultIfEmpty()
            ...

尚不清楚您为什么要调用范围变量subpet,因为它是一个人。也许是对什么的误解join ... into?有关更多详细信息,请参阅MSDN 文章join,或者我的Edulinq 博客文章查询表达式

老实说,根本不清楚为什么这个连接首先有用 - 看起来宠物只能有一个所有者,在这种情况下,您实际上只是检查是否pet.Ownerpeople. 通常,当可能有多个元素时,您会执行分组。例如,反过来更有意义:

var query = from person in people
            join pet in pets on person equals pet.Owner into gj
            from pet in gj.DefaultIfEmpty()
            ...

现在您正在寻找每个人,并列出他们的宠物 - 或者注意他们是否没有宠物。

您从查询开始时想达到什么目的?

于 2013-08-16T16:18:15.643 回答
1

由于您将其加入 gj,因此将无法访问 person。而不是person.FirstName,使用gj.FirstOrDefault().FirstName.

可能值得换成这样的东西?

var query = 
    from pet in pets
    from person in people.Where(o => o == pet.Owner).DefaultIfEmpty()
    select new
    {
        name = (person == null ? "unknown" : person.FirstName),
        PetName = pet.Name
    };
于 2013-08-16T16:19:19.957 回答