Essayer de trouver les 3 premières propriétés d'une instance de POCO
Question
J'ai un simple cours de POCO contenant les scores de l'élève.
For example:
Math - 83%
Engrish - 82%
Chemistry - 81%
Drama - 100%
etc..
Existe-t-il un moyen (en utilisant LINQ ?) le top 3 propriétés classées par score?
Je suppose que l'objet final sera un IList < T > de type anonyme, qui aura deux champs.
- Nom (le nom de la propriété)
- Score (valeur décimale).
Le nombre de propriétés dans l'objet ARE est fini, cependant:)
Des suggestions?
Comme réponse alternative, cela pourrait-il être fait dans une base de données?
La solution
Cherchez-vous quelque chose comme ça?
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);
}
}
Autres conseils
Sauf si vous avez déjà toutes les données en mémoire, il est plus efficace de laisser la base de données sélectionner les données qui vous conviennent.
Si vous stockez les notes sous forme de champs dans la base de données, vous devez les normaliser pour permettre l’interrogation. Le mieux est de repenser la base de données et de placer les notes sous forme de lignes dans un tableau séparé. Les données doivent figurer dans les champs des tables, et non en tant que noms de champs:
select top 3 GradeName, Grade
from Grades
where StudentId = 42
order by Grade desc
Vous pouvez également normaliser les données à la volée, mais ce n'est évidemment pas aussi efficace:
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
Il serait plus simple d’utiliser un dictionnaire avec le sujet comme clé et le score comme valeur:
Dictionary<string, int> scores = new Dictionary<string, int>();
...
var top3Subjects = (from s in scores
orderby s.Value descending
select s).Take(3);
Ceci renvoie un IEnumerable<KeyValuePair<string, int>>
que vous pouvez utiliser comme ceci:
foreach (var s in top3Subjects)
{
Console.WriteLine("{0} : {1}", s.Key, s.Value);
}
Dans votre question, il n’est pas clair si les partitions sont toutes des propriétés distinctes ou s’il s’agit d’une sorte de liste. Si elles sont une liste, cela fonctionnerait:
var topScores =
(from s in Scores
orderby s.Score descending
select new { s.Name, s.Score}).Take(3);