Note that there are some explanatory texts on larger screens.

plurals
  1. POStrongly Typing a LINQ Query using multiple keys of complex objects
    text
    copied!<p>I can't figure out how to define the object used in my LINQ grouping query to allow them to be strongly type.</p> <p>I've build a grouping query that uses two complex objects as keys. The query works, but I would like to be able to declare the return object type.</p> <p>I have a complex type...</p> <pre class="lang-vb prettyprint-override"><code>Public Class Student Public Name As IndividualsName Public EnrolledSchool As School Public BirthHospital As BirthPlace Public Grade As Integer Public Sub New(ByVal name As IndividualsName, ByVal enrolledSchool As School, ByVal birthHospital As BirthPlace, ByVal grade As Integer) Me.Name = name Me.EnrolledSchool = enrolledSchool Me.BirthHospital = birthHospital Me.Grade = grade End Sub End Class Public Class School Inherits Location Public Sub New(ByVal name As String, ByVal city As String, ByVal state As String) MyBase.New(name, city, state) End Sub Public Shared Function GetMyHS() As School Return New School("My High School", "My City", "My State") End Function Public Shared Function GetYourHS() As School Return New School("Your High School", "Your City", "Your State") End Function Public Shared Function GetMyElementry() As School Return New School("My Elementary", "My City", "My State") End Function Public Shared Function GetMyMiddleSchool() As School Return New School("My Middle School", "My City", "My State") End Function End Class Public Class IndividualsName Public First As String Public Last As String Public Sub New(ByVal first As String, ByVal last As String) Me.First = first Me.Last = last End Sub Public Overrides Function ToString() As String Return First &amp; " " &amp; Last End Function End Class Public Class BirthPlace Inherits Location Public Sub New(ByVal name As String, ByVal city As String, ByVal state As String) MyBase.New(name, city, state) End Sub Public Shared Function GetMyHospital() As BirthPlace Return New BirthPlace("My General Hospital", "My City", "My State") End Function Public Shared Function GetYourHospital() As BirthPlace Return New BirthPlace("Your General Hospital", "Your City", "Your State") End Function End Class Public Class Location Public Name As String Public City As String Public State As String Public Sub New(ByVal name As String, ByVal city As String, ByVal state As String) Me.Name = name Me.City = city Me.State = state End Sub Public Overrides Function Equals(ByVal obj As Object) As Boolean Return Me.GetHashCode = obj.GetHashCode End Function Public Overrides Function GetHashCode() As Integer Dim returnValue As Integer returnValue = Me.Name.GetHashCode() Xor Me.City.GetHashCode() Xor Me.State.GetHashCode() Return returnValue End Function End Class </code></pre> <p>That I'm collecting in a list and grouping together based on two complex keys.</p> <pre class="lang-vb prettyprint-override"><code>Sub Main() Dim students As List(Of Student) = New List(Of Student) students.Add(New Student(New IndividualsName("Bill", "Jones"), School.GetMyHS(), BirthPlace.GetMyHospital(), 9)) students.Add(New Student(New IndividualsName("George", "Jamesen"), School.GetMyHS(), BirthPlace.GetMyHospital(), 11)) students.Add(New Student(New IndividualsName("Chris", "McCartney"), School.GetYourHS(), BirthPlace.GetMyHospital(), 9)) students.Add(New Student(New IndividualsName("Sara", "Smith"), School.GetMyMiddleSchool(), BirthPlace.GetMyHospital(), 7)) students.Add(New Student(New IndividualsName("Josh", "Jefferies"), School.GetMyMiddleSchool(), BirthPlace.GetYourHospital(), 8)) students.Add(New Student(New IndividualsName("Mel", "Tompson"), School.GetMyHS(), BirthPlace.GetMyHospital(), 12)) students.Add(New Student(New IndividualsName("Jill", "Schmidt"), School.GetYourHS(), BirthPlace.GetMyHospital(), 10)) students.Add(New Student(New IndividualsName("Beth", "Taylor"), School.GetMyElementry(), BirthPlace.GetMyHospital(), 5)) students.Add(New Student(New IndividualsName("Mark", "Thatcher"), School.GetMyElementry(), BirthPlace.GetMyHospital(), 4)) students.Add(New Student(New IndividualsName("Tom", "Jones"), School.GetMyHS(), BirthPlace.GetYourHospital(), 9)) students.Add(New Student(New IndividualsName("Kevin", "Woo"), School.GetMyMiddleSchool(), BirthPlace.GetYourHospital(), 7)) Dim groupedQuery 'As IEnumerable(Of IGrouping()) groupedQuery = From student In students _ Group student By student.EnrolledSchool, student.BirthHospital Into Group _ Select EnrolledSchool, BirthHospital, StudentGroup = Group For Each groupItem In groupedQuery Console.WriteLine(String.Format("School: {0}, Birth Place: {1}", groupItem.EnrolledSchool.Name, groupItem.BirthHospital.Name)) 'Console.WriteLine(String.Format("Group Item is type {0}.", groupItem.GetType())) For Each item As Student In groupItem.StudentGroup Console.WriteLine(String.Format("Name: {0} - Grade: {1}", item.Name.ToString(), item.Grade.ToString())) Next Next End Sub </code></pre> <p>Everything works, but it bothers me that when I process the data collection everything is declared anonymously. This is especially bothersome the object the creates the grouped list is in one assembly and it's being consumed in a web service and on a web site.</p> <p>I would really like to be able to strongly type the IEnumberable that's being returned, but I can't figure out how to declare my <a href="http://msdn.microsoft.com/en-us/library/bb344977.aspx" rel="nofollow noreferrer">IGrouping interface</a>.</p> <p>I should be able to transverse my data structure like...</p> <pre class="lang-vb prettyprint-override"><code> Dim groupedQuery As IEnumerable(Of IGrouping(Of IDoNotKnowHowToDeclareMyComplexKey, Student)) groupedQuery = From student In students _ Group student By student.EnrolledSchool, student.BirthHospital Into Group _ Select EnrolledSchool, BirthHospital, StudentGroup = Group For Each groupItem As IGrouping(Of IDoNotKnowHowToDeclareMyComplexKey, Student) In groupedQuery Console.WriteLine(String.Format("School: {0}, Birth Place: {1}", groupItem.Key.Name) For Each item As Student In groupItem Console.WriteLine(String.Format("Name: {0} - Grade: {1}", item.Name.ToString(), item.Grade.ToString())) Next Next </code></pre> <p>but so far I haven't been able to figure out how to declare my IGrouping type.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload