2013-03-26 106 views
1

我是一个.NET中的老蜜蜂,但Linq很新!经过一些基本的阅读后,我决定检查我的技能,我完全失败了!我不知道我在哪里犯错。在每个组中过滤后选择排名前N记录

我要选择最高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()); 
      } 
     } 

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

在此先感谢

回答

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 
+0

啊,这是正确的。非常感谢你。 – 2013-03-26 01:10:21

+0

没问题 - 很高兴我能帮到:) – 2013-03-26 01:11:20

+1

打我也是这样,这个错误的原因是由于ForEach()返回void因为它实际上修改自己,所以它不需要返回任何东西。所以你的'结果'将是空的 – Corylulu 2013-03-26 01:11:57

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()); 
      } 
     } 
    }