Bonjour, j'utilise linq to entity dans mon application. J'ai besoin d'obtenir des enregistrements distincts sur la base d'une valeur de colonne "Nom"
J'ai donc un tableau similaire comme vous pouvez le voir ci-dessous:
(User)
ID
Name
Country
DateCreated
Je dois sélectionner tous ces éléments mais uniques en fonction du nom (unique). Est-il possible d'accomplir en utilisant linq, si oui, montrez-moi comment.
var items = (from i in user select new {i.id, i.name, i.country, i.datecreated}).Distinct();
La méthode Distinct()
ne fonctionne pas bien car elle n'envoie pas le prédicat DISTINCT SQL à la base de données. Utilisez à la place group
:
var distinctResult = from c in result
group c by c.Id into uniqueIds
select uniqueIds.FirstOrDefault();
Le groupe de LINQ crée en fait des sous-groupes d'entités saisis par la propriété que vous indiquez:
Smith
John
Mary
Ed
Jones
Jerry
Bob
Sally
La syntaxe ci-dessus renvoie les clés, résultant en une liste distincte. Plus d'informations ici:
La manière purement LINQ qui se produit est de regrouper par nom, de sélectionner des groupes distincts par clé, puis de sélectionner en fonction de cela.
from i in user
group new {i.ID, i.Country, i.DateRecord} by i.Name into byNmGp
select byNmGp.First();
Edit: Entity Framework est bien sûr un fournisseur linq très populaire, mais il ne gère pas bien First()
ici, bien que l'équivalent logique (dans ce cas) FirstOrDefault()
fonctionne correctement. Je préfère First()
lorsqu'il n'est pas forcé dans FirstOrDefault()
par les limitations d'EF, car sa signification correspond mieux à ce qui est recherché ici.
Une autre façon consiste à définir une classe d'assistance:
private class MyRecord : IEquatable<MyRecord>
{
public int ID;
public string Name;
public string Country;
public DateTime DateCreated;
public bool Equals(MyRecord other)
{
return Name.Equals(other.Name);
}
public override bool Equals(object obj)
{
return obj is MyRecord && Equals((MyRecord)obj);
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
/*...*/
var items = (from i in user select new MyRecord {i.ID, i.Name, i.Country, i.DateRecord}).Distinct();
Cela définit simplement distinctement différemment. Les performances diffèrent selon que le fournisseur de requêtes peut interpréter cette définition de l'égalité ou non. La commodité diffère selon que vous avez des requêtes LINQ similaires faisant à peu près la même chose ou non.
Vous pouvez utiliser quelque chose comme ceci:
var distinctReports = reports.Select(c => c.CompanyCode)
.Distinct()
.Select(c => reports.FirstOrDefault(r => r.CompanyCode == c))
.ToList();
Voici une autre variante que j'ai finalement utilisée, basée sur la réponse de Svetlana. Affiche un exemple de remplissage d'un contrôle GridView avec des valeurs uniques. Merci!
dataGridView_AnalyzeTestSuites.DataSource = (
from tr in _db.TestResults
where tr.TaskId == taskId
select new { TestSuiteName = tr.Test.TestSuite.Name }
).Distinct().ToList();
Bonjour, voici comment sélectionner des enregistrements distincts avec une jointure interne. J'espère que ça aide
var distinctrecords =
(entity.Table.Join(entity.Table2, x => x.Column, y => y.Column, (x, y) => new {x, y})
.Select(@t => new {@t.x.Column2, @t.y.Column3}))
.GroupBy(t => t.Column2)
.Select(g => g.FirstOrDefault());