Anonymer Typ mit Linq und Guid

8

Ich habe eine einfache Tabelle:

ID | Wert

Wenn ich das tue:

%Vor%

jedes Element in der Projektion hat den Wert der gleichen Guid ... Wie schreibe ich das, so dass ich einen anderen zufälligen Guid-Wert für jedes Element in der Projektion bekomme?

Bearbeiten

Zur Klärung des Problems. Die Methode GetTable () ruft einfach Folgendes auf:

%Vor%

wobei der this.contenxt der DataContext vom Typ T ist.

Die Iteration wird wie immer gemacht, nichts Besonderes:

%Vor%

Ausgabe:

%Vor%

Bearbeiten 2 Verwenden Sie die Box linq2Sql Provider. Ich habe einige generische Wrapper um es herum gebaut, aber sie ändern nicht die Art und Weise wie IQuarable oder IEnumerable im Code.

    
dexter 10.03.2011, 21:24
quelle

4 Antworten

6

Was ist unter valuesVault.GetTable() ?

Sie haben wahrscheinlich einen Linq-Provider wie Linq 2 SQL.

Das bedeutet, dass valuesVault.GetTable() vom Typ IQueryable ist, was wiederum bedeutet, dass die gesamte Abfrage zu Ausdruck .

Ein Ausdruck ist eine Abfrage , die definiert, aber noch nicht ausgeführt wurde.

Wenn sequence iteriert wird, wird die Abfrage unter Verwendung des Linq-Anbieters und des Linq-Anbieters ausgeführt und einer der Schritte, die ausgeführt werden müssen, besteht darin, diesen Ausdruck auszuführen: Guid.NewGuid() . Die meisten Linq-Provider können diesen Ausdruck nicht an die zugrunde liegende Quelle übergeben (SQL Server würde nicht wissen, was damit zu tun ist), so dass er einmal ausgeführt wird und das Ergebnis der Ausführung mit dem Rest des Ergebnisses zurückgegeben wird.

Sie können den Ausdruck valuesVault.GetTable() zu einer Sammlung machen, indem Sie die Methoden .ToList() oder .ToArray() aufrufen. Dadurch wird der Ausdruck ausgeführt und ein IEnumerable zurückgegeben, das eine speicherinterne Auflistung darstellt.

Bei der Ausführung von Abfragen für IEnumerable wird die Ausführung nicht an den Linq-Provider übergeben, sondern von der .NET-Laufzeit ausgeführt.

In Ihrem Fall bedeutet dies, dass der Ausdruck Guid.NewGuid() korrekt ausgeführt werden kann.

Versuchen Sie Folgendes:

%Vor%

Beachten Sie das .ToArray () dort. Dadurch wird die Anweisung von IQueryable auf IEnumerable gesetzt und das Verhalten wird geändert.

    
Mikael Östberg 10.03.2011, 21:29
quelle
4

Ich denke, dass es passiert, wenn es in SQL übersetzt wird (zB: es tut die Datenbank). Da Sie in Ihrem Beispiel keine WHERE-Klauseln haben, können Sie einfach Folgendes tun:

%Vor%

Dies zwingt Guid.NewGuid (), im Client ausgeführt zu werden. Es ist jedoch hässlich, wenn Ihr Tisch wächst und Sie Filterklauseln hinzufügen. Sie können es lösen, indem Sie eine zweite LINQ-Abfrage verwenden, die eine zweite Ergebnismenge mit Ihren neuen GUIDs projiziert:

%Vor%     
C. Lawrence Wenham 10.03.2011 21:31
quelle
2

Scheint für mich zu arbeiten.

%Vor%

Ausgabe

%Vor%     
Bala R 10.03.2011 21:31
quelle
1

Ich kann dieses Verhalten nicht mit einer einfachen LINQ-Abfrage reproduzieren. Beispiel:

%Vor%

Ich stelle mir vor, wenn Sie versuchen, Ihren Tabellenwert in Linq in eine Liste zu konvertieren, dann führen Sie Ihre Auswahl durch, Sie erhalten dann verschiedene Guids.

    
Tejs 10.03.2011 21:31
quelle

Tags und Links