2014-11-23 4 views
1

Я новичок в 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 

Однако то, что точка ЗЕЬЕСТА, как на этом основании можно выбрать только полные объекты.

ответ

2

Если ваш результат больше не содержит 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) } 
+0

Спасибо. Неплохо ли использовать анонимные типы? +1. – w0051977

+0

Нет, все в порядке. Просто имейте в виду, что вы не можете вернуть анонимный тип или передать его подпрограмме, поэтому это полезно только в вашем текущем методе. Тип возврата не обязательно должен быть анонимным, кстати: 'Select New SomeClassOfMine (p.Name, p.Age)' отлично. – Heinzi

+0

Я думаю, вы можете вернуть список лиц с уровня доступа к данным, а затем использовать аномальные типы на бизнес-уровне по мере необходимости? – w0051977

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. Очевидно, что это тривиальный пример, но на практике вы можете многое сделать с этим подходом.

Смежные вопросы