使用复杂对象的多个键强烈输入LINQ查询 [英] Strongly Typing a LINQ Query using multiple keys of complex objects

查看:209
本文介绍了使用复杂对象的多个键强烈输入LINQ查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法弄清楚如何定义我的LINQ分组查询中使用的对象,以使它们成为强类型。



我构建了一个分组查询它使用两个复杂的对象作为键。该查询的工作原理,但我希望能够声明返回对象类型。

我有一个复杂的类型...

Public Class Student
Public Name As IndividualsName
Public EnrolledSchool As School
Public Birth Hospital作为BirthPlace
Public Grade As Integer

Public Sub New(ByVal name As IndividualsName,ByVal enrolledSchool As School,ByVal birth Hospital 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
继承位置


公共子新建(ByVal name As String,ByVal city As String,ByVal state As String)
MyBase.New(名称,城市,州)
结束小组

公共共享函数GetMyHS()作为学校
返回新学校(我的高中,我的城市,我的州)
结束功能
公共共享功能GetYourHS()作为学校
返回新学校高中,你的城市,你的州)
结束功能
公共共享功能GetMyElementry()作为学校
返回新学校(我的小学,我的城市, 我的州)
结束功能
公共共享功能GetMyMiddleSchool()作为学校
返回新学校(我的中学,我的城市,我的州)
结束函数

结束类

公共类IndividualsName
公共首先作为字符串
公共最后作为字符串

公共小组新的(ByVal first As String,ByVal last As String)
Me.First = first
Me.Last = last
End Sub

Public覆盖函数ToString()作为字符串
返回First& &最后
结束函数
结束类

公共类BirthPlace
继承位置

公共子新(ByVal name As String,ByVal city As String,ByVal state As String)
MyBase.New(name,city,state)
End Sub

公共共享函数GetMyHospital()作为BirthPlace
返回New BirthPlace (我的综合医院,我的城市,我的州)
结束功能

公共共享功能GetYourHospital()作为BirthPlace
返回New BirthPlace医院,你的城市,你的州)
结束功能
结束班

公共班级位置
公共班级位置
公共城市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

公共覆盖函数等于(ByVal obj As Object)As Boolean
返回Me.GetHashCode = obj.GetHashCode
End Function

公共覆盖函数GetHashCode()As Integer
Dim returnValue As Integer
returnValue = Me.Name.GetHashCode()Xor Me.City.GetHashCode()Xor Me.State.GetHashCode()
返回returnValue
End Function

End类

我将根据两个复杂键收集在一个列表中并进行分组。 >

Sub Main()

Dim students As List(Of Student)= New学生名单(学生)

students.Add(新学生(新的个人姓名(Bill,Jones),School.GetMyHS(),BirthPlace.GetMyHospital(),9))
学生。添加(新学生(新学生姓名(乔治,詹姆森),School.GetMyHS(),BirthPlace.GetMyHospital(),11))
students.Add(新学生(新个人姓名(克里斯,麦卡特尼),School.GetYourHS( ),BirthPlace.GetMyHospital(),9))
students.Add(新学生(新的个人姓名(Sara,Smith),School.GetMyMiddleSchool(),BirthPlace.GetMyHospital(),7))
students.Add(新学生(新个人姓名(Josh,Jefferies),School.GetMyMiddleSchool(),BirthPlace.GetYourHospital(),8))
students.Add(新生(Mel,Tompson),School.GetMyHS(),BirthPlace.GetMyHospital(),12))
students.Add(新学生(新个人姓名(Jill,Schmidt),学校)。 (新生个人姓名(Beth,Taylor),School.GetMyElementry(),BirthPlace.GetMyHospital(),5)GetYourHS(),BirthPlace.GetMyHospital(),10))
students.Add )
students.Add(New Student(New IndividualsName(Mark,Thatcher),School.GetMyElementry(),BirthPlace.GetMyHospital(),4))
students.Add(New Student New PersonalName(Tom,Jones),School.GetMyHS(),BirthPlace.GetYourHospital(),9))
students.Add(New Student(New IndividualsName(Kevi n),Woo),School.GetMyMiddleSchool(),BirthPlace.GetYourHospital(),7))

Dim groupedQuery'As IEnumerable(Of IGrouping())
groupedQuery =从学生在学生中_
组学生按student.EnrolledSchool,student.BirthHospital分组_
选择EnrolledSchool,BirthHospital,StudentGroup = Group

对于每个groupItem分组查询
控制台.WriteLine(String.Format(School:{0},Birth Place:{1},groupItem.EnrolledSchool.Name,groupItem.BirthHospital.Name))
'Console.WriteLine(String.Format(Group Item是类型{0}。,groupItem.GetType()))

对于每个项目作为学生在groupItem.StudentGroup
Console.WriteLine(String.Format(Name:{0 } - Grade:{1},item.Name.ToString(),item.Grade.ToString()))
下一个

下一个
结束Sub

一切正常,但是当我处理数据时让我感到困扰收集一切都是匿名声明。这特别令人烦恼,创建分组列表的对象在一个程序集中,并且正在Web服务和网站中使用。



我真的很想成为能够强烈键入正在返回的IEnumberable,但我无法弄清楚如何声明我的 IGrouping接口



我应该能够横切我的数据结构,如...



Dim groupedQuery As IEnumerable(Of IGrouping(Of IDoNotKnowHowToDeclareMyComplexKey,Student))
groupedQuery =来自学生在学生中_
组学生通过student.EnrolledSchool,student.BirthHospital分组_
选择EnrolledSchool,BirthHospital,StudentGroup = Group

对于每个groupItem作为IGrouping(的IDoNotKnowHowToDeclareMyComplexKey,Student)在分组查询
Console.WriteLine(String.Format(School:{0},Birth Place:{1},groupItem.Key.Name)
对于每个项目作为学生在groupItem
Console.WriteLine(String。格式(名称:{0} - 年级:{1},item.Name.ToString(),item.Grade.ToString()))
下一个

下一个

但到目前为止,我还无法弄清楚如何声明我的IGrouping类型。

解决方案

正如Bryan所说,创建一个新的类:





<公共班级SomeName
Public EnrolledSchool As School
Public Birth Hospital作为BirthPlace
Public StudentGroup As IEnumerable(Of Student)
End Class

然后在分组时使用它:

Dim result As IEnumerable(Of SomeName)
result =(from student in students _
Group student By student。 Enro lledSchool,student.BirthHospital Into Group _
选择New SomeName with {.EnrolledSchool = EnrolledSchool,.BirthHospital = BirthHospital,.StudentGroup = Group})

如果您有任何问题,请将您的代码和错误提交给您。


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.

解决方案

As Bryan said, create a new class:

Public Class SomeName
    Public EnrolledSchool As School
    Public BirthHospital As BirthPlace
    Public StudentGroup As IEnumerable(Of Student)
End Class

Then use it while grouping:

Dim result As IEnumerable(Of SomeName)
result = (From student In students _
 Group student By student.EnrolledSchool, student.BirthHospital Into Group _
 Select New SomeName With {.EnrolledSchool = EnrolledSchool, .BirthHospital = BirthHospital, .StudentGroup = Group})

If you have any problems, place here your code and errors you get.

这篇关于使用复杂对象的多个键强烈输入LINQ查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆