I use Entity Framework Data Base First approach. I get the generated classes of this type:

 public partial class Entry { public int Id {get; set;} public string Name {get; set;} } public partial class Entry2 { public Entry2() { this.Enrties = new HashSet<Entry>(); } public virtual ICollection<Entry> Enrties {get; set;} } 

There is a need to get unique elements from a complex structure containing a collection, within each element of which there is another collection, namely, relying on the source code shown in the example and having the source data in the form of a collection:

 // list - содСрТит ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡŽ элСмСнтов Entry2, Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… коллСкция Entry List<Entry2> list; 

How to get all non-duplicate elements of type Entry contained in the list variable collection?

  • And so tried: @Π’Π°ΡˆΠ° Entry2@.Enrties.Distinct().ToList() ? Distinct You can also use Where("Π’Π°ΡˆΠ΅ условиС") Where Although, judging by the edit, you need SelectMany - Denis Bubnov
  • @Denis Bubnov; Apparently I did not quite articulate the problem. There is a collection Entry2, you need to select all the Entry contained in it. - xlmax
  • Aaaaa ... now I understand) now I will write as - Denis Bubnov

1 answer 1

You need to add a bit to your Entry class with the IEquatable interface:

 public partial class Entry : IEquatable<Entry> { public bool Equals(Entry other) { if (Object.ReferenceEquals(other, null)) return false; if (Object.ReferenceEquals(this, other)) return true; return Id.Equals(other.Id) && Name.Equals(other.Name); } public override int GetHashCode() { int hashProductName = Name == null ? 0 : Name.GetHashCode(); int hashProductCode = Id.GetHashCode(); return hashProductName ^ hashProductCode; } } 

After that, here is the code:

 // для дСмонстрации Π·Π°ΠΏΠΎΠ»Π½ΠΈΠΌ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΠΈ List<Entry2> lst = new List<Entry2>() { new Entry2() { Enrties = new List<Entry>() { new Entry() {Id = 1, Name = "1"}, new Entry() {Id = 2, Name = "2"}, new Entry() {Id = 3, Name = "3"} } }, new Entry2() { Enrties = new List<Entry>() { new Entry() {Id = 3, Name = "3"}, new Entry() {Id = 4, Name = "4"}, new Entry() {Id = 5, Name = "5"} } }, new Entry2() { Enrties = new List<Entry>() { new Entry() {Id = 5, Name = "5"}, new Entry() {Id = 6, Name = "6"}, new Entry() {Id = 7, Name = "7"} } }, }; var distinct = lst.SelectMany(x => x.Enrties).Distinct().ToList(); // 1,2,3,4,5,6,7 

As a result, only unique variables will be in the distinct variable.

Some explanations about SelectMany :

SelectMany - projects each element of a sequence into an IEnumerable<T> , merges the resulting sequences into one and calls the result selector function for each element of this sequence.

A few explanations about Distinct :

Distinct - returns distinct elements of a sequence, using the comparator for equality by default to compare values.

IEquatable inherited and Equals and GetHashCode methods were implemented so that Distinct could be compared according to our rules , and not by default.

  • The trouble is that I have a data base first, that is, entities generated based on database tables, it’s not reasonable to edit them. But thanks for the hint about SelectMany ! - xlmax
  • @xlmax, so you can use the partial class , right? - Denis Bubnov
  • @xlmax, does EF generate for you a non- partial class ? - Denis Bubnov
  • for sure! I did not think in that direction. Thank! - xlmax
  • in my case, it is not necessary to override GetHashCode, since the Entity Framework generates a SELECT DISTINCT SQL type ... - xlmax