在每个组中过滤后选择前N个记录

时间:2013-03-26 00:44:13

标签: c# linq

我是.NET中的老蜜蜂,但对Linq来说却是新手!经过一些基本的阅读后,我决定检查我的技能,但我完全失败了!我不知道我在哪里弄错了。

我想为每个人选择最高2个订单,而金额%100 == 0。

这是我的代码。

var crecords = new[] {
               new { 
                    Name = "XYZ", 
                    Orders = new[] 
                    { 
                        new { OrderId = 1, Amount = 340 }, 
                        new { OrderId = 2, Amount = 100 }, 
                        new { OrderId = 3, Amount = 200 } 
                    } 
               },
               new { 
                    Name = "ABC", 
                    Orders = new[] 
                    { 
                        new { OrderId = 11, Amount = 900 }, 
                        new { OrderId = 12, Amount = 800 }, 
                        new { OrderId = 13, Amount = 700 } 
                    } 
                }
            };


        var result = crecords
                            .OrderBy(record => record.Name)
                            .ForEach
                                (
                                    person => person.Orders
                                    .Where(order => order.Amount % 100 == 0)
                                    .OrderByDescending(t => t.Amount)
                                    .Take(2)
                                );


        foreach (var record in result)
        {
            Console.WriteLine(record.Name);
            foreach (var order in record.Orders)
            {
                Console.WriteLine("-->" + order.Amount.ToString());
            }
        }

任何人都可以关注并告诉我什么是正确的查询?

提前致谢

2 个答案:

答案 0 :(得分:3)

尝试此查询:

var result = crecords.Select(person => 
             new
                {
                    Name = person.Name, 
                    Orders = person.Orders.Where(order => order.Amount%100 == 0)
                                          .OrderByDescending(x => x.Amount)
                                          .Take(2)
                });

使用foreach循环打印生成的IEnumerable,其输出为:

XYZ
-->200
-->100
ABC
-->900
-->800

答案 1 :(得分:0)

这已经得到了解答,但如果您不想创建新对象并只是修改现有的crecords,则代码看起来会像这样。但是你不能使用你的例子中所示的匿名结构。这意味着您必须创建人员和订单类

 private class People
 {
      public string Name;
      public IEnumerable<Order> Orders;
 }

 private class Order
 {
      public int OrderId;
      public int Amount;
 }

 public void PrintPeople()
 {
      IEnumerable<People> crecords = new[] {
           new People{ 
                Name = "XYZ", 
                Orders = new Order[] 
                { 
                    new Order{ OrderId = 1, Amount = 340 }, 
                    new Order{ OrderId = 2, Amount = 100 }, 
                    new Order{ OrderId = 3, Amount = 200 } 
                } 
           },
           new People{ 
                Name = "ABC", 
                Orders = new Order[] 
                { 
                    new Order{ OrderId = 11, Amount = 900 }, 
                    new Order{ OrderId = 12, Amount = 800 }, 
                    new Order{ OrderId = 13, Amount = 700 } 
                } 
            }
        };
        crecords = crecords.OrderBy(record => record.Name);
        crecords.ToList().ForEach(
                person =>
                {
                    person.Orders = person.Orders
                          .Where(order => order.Amount%100 == 0)
                          .OrderByDescending(t => t.Amount)
                          .Take(2);
                }
            );


        foreach (People record in crecords)
        {
            Console.WriteLine(record.Name);
            foreach (var order in record.Orders)
            {
                Console.WriteLine("-->" + order.Amount.ToString());
            }
        }
    }