Pergunta

Eu tenho uma classe POCO simples que contém pontuação do aluno.

For example:
Math - 83%
Engrish - 82%
Chemistry - 81%
Drama - 100%
etc..

Existe uma maneira (usando LINQ ?) Que eu pudesse descobrir o top 3 Propriedades ordenados por pontuação?

Estou assumindo o objeto final será um IList de um tipo anônimo, que terá dois campos.

  1. Name (o nome da propriedade)
  2. Score (o valor decimal).

O número de propriedades do objecto são finitas embora:)

Todas as sugestões?

Como uma resposta alternativa, isso poderia ser feito em um banco de dados em vez disso?

Foi útil?

Solução

Você está procurando algo parecido com isto?

class Notes
{
    public double Math{ get; set; }
    public double English { get; set; }
    public double Chemistry { get; set; }
    public double Drama { get; set; }
    public string IgnoreMePlease { get; set; }
}

class Program
{
    static void PrintHighestNotes(Notes notes)
    {
        var pairs = from property in notes.GetType().GetProperties()
                     where property.PropertyType == typeof (double)
                     select new
                            {
                                Name = property.Name,
                                Value = (double) property.GetValue(notes, null)
                            };
        var result = pairs.OrderByDescending(pair => pair.Value);

        foreach (var pair in result)
            Console.WriteLine("{0} = {1}", pair.Name, pair.Value);
    }

    static void Main(string[] args)
    {
        Notes notes = new Notes()
                      {
                          Chemistry = 0.10,
                          Math = 0.2,
                          Drama = 1,
                          English = 0.3,
                          IgnoreMePlease = "Ignore"
                      };
        PrintHighestNotes(notes);
    }
}

Outras dicas

A menos que você já acontecer de ter todos os dados na memória, é mais eficiente para deixar o banco de dados, selecione os dados corretos para você.

Se você armazenar as notas como campos no banco de dados, você tem que normalizá-lo para torná-lo possível para consulta. O melhor é redesenhar o banco de dados e colocar as notas como linhas em uma tabela separada. Os dados devem estar nos campos das tabelas, não como nomes de campo:

select top 3 GradeName, Grade
from Grades
where StudentId = 42
order by Grade desc

Você também pode normalizar os dados em tempo real, mas que é, naturalmente, não tão eficiente:

select top 3 GradeName, Grade
from (
   select GradeName = 'Engrish', Grade = Engrish from Students where StudentId = 42
   union all
   select 'Drama', Drama from Students where StudentId = 42
   union all
   select 'Math', Math from Students where StudentId = 42
   union all
   select 'Chemistry', Chemistry from Students where StudentId = 42
) Grades
order by Grade desc

Seria mais simples de usar um dicionário com o assunto como a chave e o marcador quando o valor:

Dictionary<string, int> scores = new Dictionary<string, int>();
...

var top3Subjects = (from s in scores
                    orderby s.Value descending
                    select s).Take(3);

Isso retorna uma IEnumerable<KeyValuePair<string, int>>, que você pode usar como esta:

foreach (var s in top3Subjects)
{
    Console.WriteLine("{0} : {1}", s.Key, s.Value);
}

Não está claro na sua pergunta se as pontuações são todas as propriedades separadas ou se é algum tipo de lista. Se eles são uma lista, isso iria funcionar:

 var topScores =
    (from s in Scores
    orderby s.Score descending
    select new { s.Name, s.Score}).Take(3);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top