2016-01-05 1 views
2

Je les classes suivantes avec ces champsC# - requête LINQ à cette fin

public class Account { 
    public int Id { get; set; } 
    public string Username { get; set; } 
    public float Timezone { get; set; } 
} 

public class Player { 
    public int Id { get; set; } 
    public virtual Account Account { get; set; } 
    public string Team_Name { get; set; } 
} 

Supposons maintenant que j'ai une liste <> du joueur appelé joueurs, chaque équipe dispose de 2 joueurs, cela signifie que tous les TEAM_NAME sera répété deux fois. Par exemple. L'équipe X a le joueur A et le joueur B, deux entrées dans la liste <> du joueur pour représenter cela. Ce que je veux faire, c'est former des équipes les unes par rapport aux autres en fonction du fuseau horaire, puisque chaque équipe a 2 joueurs. Je devrais calculer le fuseau horaire moyen pour chaque équipe en accédant au champ Account.Timezone dans la classe Player, puis trouver une autre équipe Fuseau horaire moyen pour faire correspondre l'équipe contre eux.

Example

+0

Pour la sortie Je veux juste une liste triée <> du joueur, il sera index [0] équipe vs index [1] dans la liste et ainsi de suite ... il ne devrait pas y avoir d'entrée dupliquée de team_name dans la sortie – HappySylveon

+0

Y a-t-il une raison de ne pas avoir une classe 'Team' contenant des joueurs à la place? – juharr

+0

Oui parce qu'en fait il y a une troisième classe appelée Tournois, la classe Joueur est juste là pour faire la relation plusieurs à plusieurs entre les Comptes et les Tournois, je ne l'ai pas incluse car elle n'est pas nécessaire pour résoudre. – HappySylveon

Répondre

1

Vous pouvez utiliser GroupBy() pour regrouper vos List<Player> par TEAM_NAME et aller de là.

Cependant, ma préférence serait de créer une nouvelle entité Team et de donner à cette entité les propriétés Player1 et Player2, ou une propriété List<Player> Players. Je voudrais alors avoir un getter TeamTimezone qui calcule le fuseau horaire moyen des joueurs de l'équipe. L'ajout d'une classe pour représenter le concept d'équipe exprime plus clairement ce que fait votre programme, le rendant plus compréhensible et réduisant les risques de bugs.

+0

Bonne idée, merci. – HappySylveon

3

En supposant que vous avez une classe Match comme ceci:

public class Match 
{ 
    public string Team1 { get; set; } 
    public string Team2 { get; set; } 
} 

Vous pouvez faire quelque chose comme ça avec LINQ:

var matches = 
    Players.GroupBy(player => player.Team_Name) //Group players by team name 
     .Select(
      team => //For each team 
       new 
       { 
        TeamName = team.Key, //Select team name 
        AverageTimezone = //And average time zone 
         team.Average(player => player.Account.Timezone) 
       }) 
     .OrderBy(team => team.AverageTimezone) //Order teams by average time zone 
     .Select((team, index) => new {Team = team, Index = index}) 
     .GroupBy(item => item.Index/2) //Group each two teams together (since the teams are ordered by average timezone, each two teams will have a close timezone) 
     .Select(g => g.Select(item => item.Team).ToList()) 
     .Select(g => new Match 
     { 
      Team1 = g[0].TeamName, 
      Team2 = g[1].TeamName 
     }) 
     .ToList(); 
+0

La moyenne peut simplement être 'team.Average (player => player.Account.Timezone)' – juharr

+0

@juharr, à droite. J'ai mis à jour la réponse. –

+0

Merci, mais je ne sais pas ce qui se passerait si la liste <> des Joueurs avait un nombre impair d'entrées – HappySylveon