2009-02-09 13 views
17

Co (jeśli występuje) jest różnica między wynikami dwóch poniższych wersji tego zapytania VB Linq?Co robi składnia "New ... With" w VB Linq?

"Zakładamy, mamy Xelement zawierający dane pracownika zdefiniowane gdzie indziej

Dim ee = From e In someXML.<Employee> _ 
Select New With {.Surname = e.<Surname>, .Forename = e.<Forename>} 

i

Dim ee = From e In someXML.<Employee> _ 
Select Surname = .Surname = e.<Surname>, .Forename = e.<Forename> 

czyli co jest punktem nowego ... Z składni?

Podejrzewam, że ma to prostą odpowiedź, ale nie mogę go znaleźć - mile widziane będą wszelkie linki do odpowiednich samouczków lub dokumentacji Microsoft.

Odpowiedz

14

Różnica polega na tym, że pierwsza jawnie tworzy anonimowy typ. Drugi to wyrażenie zapytania i może używać istniejącego typu zamiast tworzyć anonimowy typ. Z dokumentacji powiązanej z Cameron MacFarland:

Wyrażenia kwerendy nie zawsze wymagają utworzenia typów anonimowych. Jeśli to możliwe, używają istniejącego typu do przechowywania danych kolumny. Dzieje się tak, gdy zapytanie zwraca całe rekordy ze źródła danych lub tylko jedno pole z każdego rekordu.

+0

Czy to nie znaczy, że podczas wybierania kolumny _single_ nie ma anonimowego typu? Tak więc nie ma zastosowania do powyższego przykładu, w którym używane są 2 kolumny. –

+0

Tak, prawdopodobnie nie ma różnicy w tym przykładzie. Ale w przypadku _general_ jest to różnica_potencjalna_. Może również użyć istniejącego typu, jeśli przywrócisz cały rekord, więc nie jest to tylko dla pojedynczych kolumn. –

+0

Obie wersje kodu używają zawsze anonimowego typu. – JaredPar

1

Nazywają się Anonymous Types.

Głównym powodem ich wykorzystania jest przechowywanie danych z zapytania w jednym obiekcie, aby można było kontynuować iteracje nad listą obiektów.

Zwykle pracują jako tymczasowe typy do przechowywania w środku dużej lub wieloczęściowej kwerendy LINQ.

+0

Tak - wiem, czym one są, ale jaka, jeśli w ogóle, jest różnica między tymi dwoma formami składni? Podany link podaje przykład obu formularzy, ale nie mówi, czy są one równoważne. –

+0

Oczywiście, że tak: wskazałem dokładnie, gdzie w tym łączu dla ciebie. –

+0

ok - połączenie twojego związku Cameron z wyjaśnieniem Joela ma teraz sens. Bardzo wam wszystkim dziękuję. –

2

Rozumiem, że nie ma różnicy.

New With skierowany jest do out-of-zapytania wykorzystanie jak

Dim X = New With { .Surname = "A", .Forename = "B" } 

szczególności dla zapytań LINQ, można pominąć New With, ale wciąż jest użyteczny dla innych sytuacjach. Nie jestem jednak pewien, ponieważ nie wiem, VB 9 :)

+0

W zależności od zapytania, niestandardowe dodane właściwości dodane w klasach częściowych lub inne pola będą tylko do odczytu, jeśli nie zostaną zwrócone w jawnym typie anonimowym, przy użyciu składni Wybierz nową ze składnią {}. – Nathan

0

Jedną z różnic jest to, że typów anonimowych nie można szeregować.

2

Nie ma różnicy funkcjonalnej między dwoma wymienionymi kodami. Pod maską, kod obu sztuk użyje anonimowego typu, aby zwrócić dane z zapytania.

Pierwszy fragment kodu sprawia, że ​​użycie anonimowego typu jest jawne. Przyczyną tej składni jest to, że można zwrócić dowolny typ z klauzuli Select. Ale typ musi być jawnie użyty.

Dim x = From it in SomeCollection Select New Student With { .Name = it.Name } 

Joel jest nieprawidłowy w swoim stwierdzeniu, że drugie zapytanie może używać istniejącego typu. Bez jawnego typu klauzula select, która używa jawnej nazwy właściwości, zawsze zwróci anonimowy typ.

1

Nie ma różnicy. Kompilator wywnioskuje typ anonimowy.

Najprawdopodobniej chcesz zwrócić wartość elementów, jak w e.<Surname>.Value, która zwraca ciąg zamiast XElement.

Twój 2-ci Przykładem może być uproszczona

Dim ee = From e In someXML.<Employee> _ 
     Select e.<Surname>.Value, e.<Forename>.Value 

ponieważ kompilator będzie również wnioskować, nazwiska członków anonimowego typu.

Jednakże, jeśli mają następujące klasy

Class Employee 

    Private _surname As String 
    Public Property Surname() As String 
     Get 
      Return _surname 
     End Get 
     Set(ByVal value As String) 
      _surname = value 
     End Set 
    End Property 

    Private _forename As String 
    Public Property Forename() As String 
     Get 
      Return _forename 
     End Get 
     Set(ByVal value As String) 
      _forename = value 
     End Set 
    End Property 

End Class 

Następnie można zmienić 1st zapytanie do wytworzenia IQueryable(Of Employee) zamiast anonimowego typu poprzez wykorzystanie nowych ... Z tak:

Dim ee = From e In someXML.<Employee> _ 
     Select New Employee With {.Surname = e.<Surname>.Value, _ 
            .Forename = e.<Forename>.Value}