使用复杂对象的多个键强类型化 LINQ 查询
我不知道如何定义 LINQ 分组查询中使用的对象以允许它们成为强类型。
我构建了一个使用两个复杂对象作为键的分组查询。该查询有效,但我希望能够声明返回对象类型。
我有一个复杂的类型......
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 & " " & 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
我将其收集在一个列表中并根据两个复杂的键分组在一起。
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
一切正常,但令我困扰的是,当我处理数据收集时,所有内容都是匿名声明的。这是特别麻烦的,因为创建分组列表的对象位于一个程序集中,并且正在 Web 服务和网站上使用它。
我真的希望能够强类型化返回的 IEnumberable,但我不知道如何声明我的 I分组界面.
我应该能够像...一样横贯我的数据结构,
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
但到目前为止我还无法弄清楚如何声明我的 IGrouping 类型。
I can't figure out how to define the object used in my LINQ grouping query to allow them to be strongly type.
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.
I have a complex type...
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 & " " & 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
That I'm collecting in a list and grouping together based on two complex keys.
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
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.
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 IGrouping interface.
I should be able to transverse my data structure like...
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
but so far I haven't been able to figure out how to declare my IGrouping type.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如 Bryan 所说,创建一个新类:
然后在分组时使用它:
如果您有任何问题,请将您的代码和错误放在此处。
As Bryan said, create a new class:
Then use it while grouping:
If you have any problems, place here your code and errors you get.
根据定义,如果某物是匿名的,则无法通过名称来称呼它。
您应该创建一个代表复杂键类型的新类,并使用它而不是匿名类型。
By definition, if something is anonymous, you can't call it by a name.
You should create a new class that represents your complex key type, and use that instead of anonymous types.