2009-02-09 6 views
17

Was (falls vorhanden) ist der Unterschied zwischen den Ergebnissen der folgenden zwei Versionen dieser VB Linq-Abfrage?Was macht die "New ... With" -Syntax in VB Linq?

'nehmen wir haben eine XElement enthalten Mitarbeiterdaten woanders definiert

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

und

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

dh was ist der Sinn des neuen ... Mit Syntax?

Ich vermute, dass dies eine einfache Antwort hat, aber ich kann es nicht finden - Links zu geeigneten Tutorials oder Microsoft-Dokumentation würden geschätzt.

Antwort

14

Der Unterschied ist, dass der erste explizit einen anonymen Typ erstellt. Der zweite ist ein Abfrageausdruck und kann einen vorhandenen Typ verwenden, anstatt einen anonymen Typ zu erstellen. Aus der von Cameron MacFarland verknüpften Dokumentation:

Abfrageausdrücke erfordern nicht immer die Erstellung anonymer Typen. Wenn möglich, verwenden sie einen vorhandenen Typ, um die Spaltendaten zu speichern. Dies tritt auf, wenn die Abfrage entweder ganze Datensätze aus der Datenquelle oder nur ein Feld aus jedem Datensatz zurückgibt.

+0

Bedeutet es nicht nur, dass wenn Sie eine _single_ Spalte auswählen, es keinen anonymen Typ gibt? Dies trifft nicht auf das obige Beispiel zu, in dem 2 Spalten verwendet werden. –

+0

Ja, es gibt wahrscheinlich keinen Unterschied in diesem Beispiel. Aber im allgemeinen Fall ist das der Potentialunterschied. Außerdem kann ein vorhandener Typ verwendet werden, wenn Sie den gesamten Datensatz zurückholen, also nicht nur für einzelne Spalten. –

+0

Beide Teile des Codes verwenden immer einen anonymen Typ. – JaredPar

1

Sie heißen Anonymous Types.

Der Hauptgrund für ihre Verwendung besteht darin, die Daten einer Abfrage in einem einzelnen Objekt zu behalten, damit die Iteratoren weiterhin über eine Liste von Objekten iterieren können.

Sie neigen dazu, als temporäre Typen für die Speicherung in der Mitte einer großen oder mehrteiligen LINQ-Abfrage zu arbeiten.

+0

Ja - ich weiß, was sie sind, aber was, wenn überhaupt, ist der Unterschied zwischen diesen beiden Formen der Syntax? Der von Ihnen angegebene Link gibt ein Beispiel für beide Formen, sagt aber nicht, ob sie gleichwertig sind. –

+0

Sicher tut es: Ich wies genau darauf hin, wo in diesem Link für Sie. –

+0

ok - Kombinieren Sie Ihren Link Cameron mit Joels Erklärung macht jetzt Sinn. Danke euch allen. –

2

Mein Verständnis ist, dass es keinen Unterschied gibt.

New With richtet sich an out-of-Abfrage Nutzung wie

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

Speziell für Linq-Abfragen Sie New With überspringen können, aber es ist immer noch nützlich für andere Situationen. Ich bin mir jedoch nicht sicher, da ich VB 9 nicht kenne :)

+0

Abhängig von der Abfrage werden benutzerdefinierte Eigenschaften hinzugefügt, die Sie in Teilklassen hinzugefügt haben, oder andere Felder sind schreibgeschützt, wenn sie nicht in einem expliziten anonymen Typ zurückgegeben werden, indem Sie die Option Neu mit {} auswählen. – Nathan

0

Ein Unterschied ist, dass anonyme Typen nicht serialisierbar sind.

2

Zwischen den beiden aufgelisteten Codeabschnitten besteht kein Funktionsunterschied. Unter der Haube verwenden beide Teile einen anonymen Typ, um die Daten aus der Anfrage zurückzugeben.

Der erste Teil des Codes macht lediglich die Verwendung eines anonymen Typs explizit. Der Grund dafür, dass diese Syntax zulässig ist, besteht darin, dass ein beliebiger Typ aus einer Select-Klausel zurückgegeben werden kann. Aber der Typ muss explizit verwendet werden.

Joel ist in seiner Aussage falsch, dass die zweite Abfrage einen vorhandenen Typ verwenden kann. Ohne einen expliziten Typ gibt eine SELECT-Klausel, die einen expliziten Eigenschaftsnamen verwendet, immer einen anonymen Typ zurück.

1

Es gibt keinen Unterschied. Der Compiler wird den anonymen Typ ableiten.

Wahrscheinlich möchten Sie den Wert der Elemente wie in e.<Surname>.Value zurückgeben, die einen String anstelle eines XElement zurückgibt.

Ihr zweites Beispiel könnte als

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

vereinfacht werden, da der Compiler auch die Namen der Mitglieder des anonymen Typs schließen wird.

Wenn Sie jedoch die folgende Klasse haben

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 

Dann könnten Sie die erste Abfrage ändern, um eine IQueryable(Of Employee) anstelle des anonymen Typ zu erzeugen, indem Neu mit ... Mit etwa so:

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