【问题标题】:C# Linq Inner JoinC# Linq 内连接
【发布时间】:2009-12-10 05:22:04
【问题描述】:

我只想选择养宠物的人。

当我执行查询时

var query = from p in people
                        join
                        pts in pets
                        on p equals pts.Owner into grp
                        select new {grp=grp,PersonName=p.FirstName};

没有宠物的人也会被选中。

我的列表是

Person[] prn = new Person[3];
prn[0] = new Person();
prn[0].FirstName = "Jon";
prn[0].LastName = "Skeet";

prn[1] = new Person();
prn[1].FirstName = "Marc";
prn[1].LastName = "Gravell";

prn[2] = new Person();
prn[2].FirstName = "Alex";
prn[2].LastName = "Grover";

List<Person> people = new List<Person>();

 foreach (Person p in prn)
 {
     people.Add(p);
 }

 Pet[] pt = new Pet[3];

 pt[0] = new Pet();
 pt[0].Name = "Zonny";
 pt[0].Owner = people[0];

pt[1] = new Pet();
pt[1].Name = "Duggie";
pt[1].Owner = people[0];

pt[2] = new Pet();
pt[2].Name = "Zoggie";
pt[2].Owner = people[1];

List<Pet> pets=new List<Pet>();
 foreach(Pet p in pt)
 {
    pets.Add(p);
 }

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    那是因为您使用的是join ... into,它会加入群组。你只想要一个普通的加入:

    var query = (from p in people
                 join pts in pets on p equals pts.Owner
                 select p).Distinct();
    

    或者,如果您想要有宠物的人和他们的主人,您可以这样做:

    var query = pets.GroupBy(pet => pet.Owner)
                    .Select(x => new { Owner = x.Key, Pets = x.ToList() });
    

    这将产生一个结果,您可以获取每个所有者及其宠物,但仅限于拥有宠物的人。

    如果您还想要其他东西,请告诉我们...

    顺便说一句,现在是学习对象和集合初始化器的好时机。这是初始化people 列表的更简单方法,例如:

    List<Person> people = new List<Person>
    {
        new Person { FirstName = "Jon", LastName = "Skeet" },
        new Person { FirstName = "Marc", LastName = "Gravell" },
        new Person { FirstName = "Alex", LastName = "Grover" },
    };
    

    更紧凑:)

    编辑:交叉连接很简单:

    var query = from person in people
                from pet in pets
                select new { person, pet };
    

    使用组连接可以有效地模拟左连接。听起来你已经深入了解了 C#,我建议你仔细阅读第 11 章:)

    【讨论】:

    • 'into grp' 应该消失了,不是吗? ;p
    • 看到你修好了 :) 'into' 改变了词法范围,这总是让我在 IDE 之外感到困惑。
    • 是的,我从你的书中读到了这种简单的初始化方法。
    • 是的,我想要更多的东西,我的意思是你能解释一下我如何在 Linq 中执行外连接(左、右)、内连接、交叉连接。
    • 当然,我会通读第 11 章。你有没有在你的 MisUtil 上设计过任何例子?
    【解决方案2】:

    这是一种不同的方法,只添加一行:

    var query = from p in people
                join pts in pets
                on p equals pts.Owner into grp
                where grp.Any()             // <--- added this
                select new {grp=grp,PersonName=p.FirstName};
    

    在这里我选择组,就像你一样,但我添加了一行,只选择包含至少一个元素的组,而忽略其余的。

    【讨论】:

      【解决方案3】:

      这也可以在一行代码中使用 lambda 表达式来完成...

      IEnumerable<Person> peopleWithPets = people.Where(x => pets.Any(y => y.Owner == x));
      

      【讨论】:

      • 您将如何从其中一个或两个中选择属性?例如,我需要选择 x.PetName 和 y.PetName
      猜你喜欢
      • 1970-01-01
      • 2017-10-01
      • 1970-01-01
      • 2017-06-23
      • 2010-10-06
      • 2014-07-18
      • 2017-04-10
      • 1970-01-01
      • 2019-01-29
      相关资源
      最近更新 更多