LINQ - 选择某些列

时间:2014-11-23 11:30:09

标签: vb.net linq

我是LINQ的新手。请参阅以下代码:

Public Class Person
    Public Name As String
    Public Address As String
    Public Age As String
End Class

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
        Try
            Dim p1 As New Person
            Dim p2 As New Person
            Dim p3 As New Person

            p1.Name = "Ian"
            p1.Age = 32
            p1.Address = "8 street"

            p2.Name = "Fred"
            p2.Age = 62
            p2.Address = "5 road"

            p3.Name = "Bernie"
            p3.Age = 59
            p3.Address = "5 road"

            Dim list As New List(Of Person)
            list.Add(p1)
            list.Add(p2)
            list.Add(p3)

            Dim test As IEnumerable(Of Person) = From p In list
                       Where p.Name = "Ian"
                       Select p.Name, p.Age
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try

    End Sub
End Class

我将如何循环测试?

我知道我可以这样做:

Dim test As IEnumerable(Of Person) = From p In list
                       Where p.Name = "Ian"
                       Select p
            Dim List2 As List(Of Person) = test.ToList

但是,SELECT子句的基础是什么,你只能选择完整的对象。

2 个答案:

答案 0 :(得分:4)

如果您的结果不再包含Address,则不再是Person

以下 工作:

Dim test = From p In list
           Where p.Name = "Ian"
           Select New With { .Name = p.Name, .Age = p.Age }

这将创建一个新的匿名类型,其中只包含您感兴趣的信息。test的类型为IEnumerable(Of SomeAnonymousTypeThatDoesNotHaveAName)


一般来说,Select子句的目的是进行投影。例如,您可以将您的人员投射到字符串:

Dim namesWithAges As IEnumerable(Of String) = 
    From p In list Select p.Name & " (" & p.Age & ")"

或某些全新的对象:

Dim employees = 
    From p In list
    Select New With { .Name = p.Name, .Supervisor = DetermineSupervisor(p) }

答案 1 :(得分:1)

您当然可以在他们创建的函数之外使用匿名类型。

以下是一个例子。

不是使用Dim test As IEnumerable(Of Person)的签名来定义查询,而是这样做:

Dim test = _
    From p In list
    Where p.Name = "Ian"
    Select p.Name, p.Age

编译器将推断出匿名类型。

现在,您可以在以下函数中使用它:

Public Function GetDisplayItems(Of T)(items As IEnumerable(Of T), toString As Func(Of T, String)) As String
    Return String.Join(Environment.NewLine, items.Select(toString))
End Function

此函数具有编译器可以推断的泛型类型,因此您可以使用匿名类型调用它。试试这个:

Dim text = GetDisplayItems(test, Function (t) t.Name & " " & t.Age)

Console.WriteLine(text)

我得到的结果是文字Ian 32。显然这是一个微不足道的例子,但在实践中你可以用这种方法做很多事情。