2010-12-17 3 views
12

J'écris une fonction qui tire des enregistrements d'une base de données en utilisant LINQ pour obtenir un IQueryable. Cette instruction LINQ extrait tous les enregistrements pour les utilisateurs actifs dans un certain laps de temps, puis crache l'ID utilisateur, le prénom et le nom de famille à un Telerik RadGrid.Retour d'un IQueryable distinct avec LINQ?

Mon problème réside dans essayer d'obtenir une valeur distincte sur l'ID utilisateur lors de l'extraction de ces données. J'ai essayé de retravailler ce code pour obtenir mon résultat. Voici un exemple du code qui tire toutes les données, avec le distinctif ne fonctionne pas.

public static IQueryable GetActiveEmployees_Grid(string Period) 
{ 
    DataContext Data = new DataContext(); 
    var Employees = (from c in DataSystem_Records 
        where c.Period == Period 
        orderby c.DataSystem_Employees.LName 
        select c).Distinct(); 

    return Employees; 
} 

Après avoir appliqué le DataSource à ma grille, cela renvoie l'utilisateur 4 fois, une instance pour chaque enregistrement pour cette période.

alt text

Y at-il un moyen d'appliquer Distinct à ma LINQ fonction pour faire fonctionner la façon dont je voulu?

Répondre

20

Le moyen le plus simple que j'ai trouvé pour faire cela avec un objet est d'utiliser le groupe en sélectionnant le premier.

public static IQueryable GetActiveEmployees_Grid(string Period) 
{ 
    DataContext Data = new DataContext(); 
    var Employees = (from c in DataSystem_Records 
        where c.Period == Period 
        orderby c.DataSystem_Employees.LName 
        select c).GroupBy(g=>g.DataSystem_Employees.AccID).Select(x=>x.FirstOrDefault()); 

    return Employees; 
} 

Ceci n'est pas testé mais le concept général est là.

Modifier: Je me suis souvenu d'avoir trouvé la réponse quelque part ici. Consultez ceci pour grouper des objets par une certaine propriété. LINQ's Distinct() on a particular property

+1

Le GroupBy a fonctionné parfaitement!J'ai d'abord essayé le GroupBy lors du dépannage, mais j'avais manqué le .Select (x => x.FirstOrDefault()). Merci! – Lando

+0

La commande par doit être dans le select après le groupe par avant le premierordefault. en supposant que vous vous souciez de l'heure de connexion. –

4

Si vous limitez les objets que vous retournez uniquement aux champs que vous souhaitez afficher, cela fonctionnera correctement.

public static IQueryable GetActiveEmployees_Grid(string Period) 
{ 
    DataContext Data = new DataContext(); 
    var Employees = (from c in DataSystem_Records 
        where c.Period == Period 
        orderby c.DataSystem_Employees.LName 
        select c.DataSystem_Employees.FName, 
          c.DataSystem_Employees.LName, 
          c.ID).Distinct(); 

    return Employees; 
} 
+0

En théorie, cela aurait dû marcher, mais IntelliSense m'a refusé en essayant d'ajouter plus d'une entité à la déclaration. – Lando

+0

Quelle erreur obtenez-vous? – sgriffinusa

+0

@sgriffinusa, vous devez 'select new {}' ... car votre syntaxe est invalide –

4

essayer d'écrire un IEqualityComparer<T> pour le type d'objet sélectionné et l'utiliser dans votre méthode Distinct

+2

cela va utiliser linq pour les objets pas une requête composée –

2

Faire quelques hypothèses autour des noms des différents champs dans les objets:

public static IQueryable GetActiveEmployees_Grid(string Period) 
{ 
    DataContext Data = new DataContext(); 
    var Employees = (from c in DataSystem_Records 
        where c.Period == Period 
        orderby c.DataSystem_Employees.LName 
        select new { FirstName = c.DataSystem_Employees.FName, LastName = c.DataSystem_Employees.LName, ID = c.DataSystem_Employees.ID }).Distinct(); 

    return Employees; 
} 

Pour suivre le modèle MVC, vous pouvez soulever cette requête dans votre modèle et renvoyer une classe spécifique qui contient ces champs.

-1

Le problème est que vous récupérez des champs qui vont rendre chaque rangée distincte. Comme dit sgriffinusa, ne retirez que les 3 valeurs que vous affichez.

-1

Vous souhaiterez peut-être implémenter une méthode personnalisée de comparaison de critères. Veuillez vous référer à une question SO antérieure here.

0

Utilisez la méthode Distinct() pour cela. Par exemple:

var query = from Notification in db.Notifications 

         select Notification.client ; 
      query=query.Distinct(); 

La requête résultante ne contient que des valeurs distinctes.