C# 如何使用Linq在每个记录中获取属性名的终止顺序

C# 如何使用Linq在每个记录中获取属性名的终止顺序,c#,linq,C#,Linq,考虑到下列记录: _______________________ Id S1 S2 | S3 S4 S5 | --------------------|----------------------| 1 5 7 | 8 2 5 | 2 22 24 | 7 9 10 | 3 19

考虑到下列记录:

                    _______________________
Id      S1      S2  |   S3      S4      S5 |
--------------------|----------------------|
1       5       7   |   8       2       5  |    
2       22      24  |   7       9       10 |
3       19      17  |   8       2       3  |
4       7       8   |   9       1       0  |
5       15      1   |   7       9       10 |
                    ________________________    
我想根据S3、S4、S5列中的降序从每个记录中获取前2个属性名称,类似于这些记录:

Id      1st Top     2nd Top
---------------------------
1       S3 (8)      S5 (5)  
2       S5 (10)     S4 (9) 
3       S3 (8)      S5 (3)
4       S3 (9)      S4 (1)
5       S5 (10)     S4 (9)
如何使用linq实现这一点

注:S3/S4/S5为整数型


我想要字符串值中的前2个属性名。

首先,您需要像这样修复数据:

var data = records.Select(r=>new {Id=r.Id,Field="S1",Value=r.S1})
  .Concat(records.Select(r=>new {Id=r.Id,Field="S2",Value=r.S2}))
  .Concat(records.Select(r=>new {Id=r.Id,Field="S3",Value=r.S3}))
  .Concat(records.Select(r=>new {Id=r.Id,Field="S4",Value=r.S4}))
  .Concat(records.Select(r=>new {Id=r.Id,Field="S5",Value=r.S5}));
var data = records.Select(r=>new {Id=r.Id,Field="S3",Value=r.S3})
  .Concat(records.Select(r=>new {Id=r.Id,Field="S4",Value=r.S4}))
  .Concat(records.Select(r=>new {Id=r.Id,Field="S5",Value=r.S5}));

foreach(var rec in data
  .GroupBy(z=>z.Id)
  .OrderBy(z=>z.Id))
{
  Console.WriteLine("{0} {1} ({2}) {3} ({4}), 
    rec.Key, 
    rec.OrderByDescending(f=>f.Value).First().Field,
    rec.OrderByDescending(f=>f.Value).First().Value,
    rec.OrderByDescending(f=>f.Value).Skip(1).First().Field,
    rec.OrderByDescending(f=>f.Value).Skip(1).First().Value);
}
然后您可以操纵它(尽管简单的分组方式可能更好):

这有点长,但它是最通用的。你根本不需要关注s1/s2,但我把它们放在那里只是因为你可能想对这些数据进行的其他查询可能需要它们

打印出来:

foreach(var rec in data.OrderBy(r=>r.Id))
{
  Console.WriteLine("{0} {1} ({2}) {3} ({4}), 
    rec.Id, rec.First.Field, rec.First.Value, rec.Second.Field, rec.Second.Value);
}
或者你可以这样做:

var data = records.Select(r=>new {Id=r.Id,Field="S1",Value=r.S1})
  .Concat(records.Select(r=>new {Id=r.Id,Field="S2",Value=r.S2}))
  .Concat(records.Select(r=>new {Id=r.Id,Field="S3",Value=r.S3}))
  .Concat(records.Select(r=>new {Id=r.Id,Field="S4",Value=r.S4}))
  .Concat(records.Select(r=>new {Id=r.Id,Field="S5",Value=r.S5}));
var data = records.Select(r=>new {Id=r.Id,Field="S3",Value=r.S3})
  .Concat(records.Select(r=>new {Id=r.Id,Field="S4",Value=r.S4}))
  .Concat(records.Select(r=>new {Id=r.Id,Field="S5",Value=r.S5}));

foreach(var rec in data
  .GroupBy(z=>z.Id)
  .OrderBy(z=>z.Id))
{
  Console.WriteLine("{0} {1} ({2}) {3} ({4}), 
    rec.Key, 
    rec.OrderByDescending(f=>f.Value).First().Field,
    rec.OrderByDescending(f=>f.Value).First().Value,
    rec.OrderByDescending(f=>f.Value).Skip(1).First().Field,
    rec.OrderByDescending(f=>f.Value).Skip(1).First().Value);
}
或者,如果对您更有意义,您可以像这样生成规范化数据:

var data = records.Select(r=> new {
  Id=r.Id,
  Values=new[]{
    new {Field="S3",Value=r.S3},
    new {Field="S4",Value=r.S4},
    new {Field="S5",Value=r.S5}}});

毫无疑问:
1
:保存此数据的变量类型是什么?是数据库里的吗<代码>2:如何计算第二个顶部和第一个顶部<代码>3:您希望的类型是什么。当您提出下一个问题时,请提供一份一般说明,说明您的问题、样本输入、预期输出等