2010-05-25 10 views
6

Ok ich habe folgende, Einrichtung und funktioniert super. Diese Codezeilen sollten eine Konvertierung von DAL Entity (Subsonic) zu einem ViewModel durchführen.Loop zu LINQ Conversion -

IList<ProductOptionModel> OptionsRetData = new List<ProductOptionModel>(); 

    foreach (var CurProductOption in this.ProductOptions) 
    { 
     OptionsRetData.Add(CurProductOption.ToDataModel()); 
    } 

    returnData.Options = OptionsRetData.AsEnumerable(); 

Ich möchte dies in eine LINQ Single Line Statment konvertieren und kam auf die folgenden.

returnData.Options = this.ProductOptions.Select(o => o.ToDataModel()); 

und ich empfange den folgenden Fehler.

Server Error in '/' Application. 
Sequence contains no matching element 

Also warum funktioniert die erste Anweisung, aber nicht die LINQ und, welche Schritte kann ich nehmen, um es zu lösen.

Stack Trace

bei System.Linq.Enumerable.First [TSource] (IEnumerable 1 source, Func 2 Prädikats) bei SubSonic.Extensions.Database.Load [T] (IDataReader RDR, T Einzelteil, Liste 1 ColumnNames) at SubSonic.Extensions.Database.ToEnumerable[T](IDataReader rdr, List 1 Column) bei SubSonic.Linq.Structure.DbQueryProvider.Execute [T] (QueryCommand 1 query, Object[] paramValues) at lambda_method(Closure) at SubSonic.Linq.Structure.DbQueryProvider.Execute(Expression expression) at SubSonic.Linq.Structure.Query 1.GetEnumerator()

Vielleicht ist das mit subsonic zu tun?

+2

Was ist der Call-Stack der Ausnahme? – SLaks

+0

Was ist der Rückgabetyp von ToDataModel()? –

+0

@Dave Swersky - Rückgabetyp ist ProductOptionModel – LiamB

Antwort

7

Eine Möglichkeit ist, dass es nicht funktioniert, weil Sie den Zeitpunkt geändert haben, zu dem die Abfrage materialisiert wird. Ändern Sie stattdessen den Code:

returnData.Options = this.ProductOptions.Select(o => o.ToDataModel()).ToList(); 

Das wird erzwingen, dass die Abfrage zur gleichen Zeit wie zuvor ausgewertet wird.

EDIT: Ihre Stack-Trace zeigt First() wird irgendwie aufgerufen, aber wir haben nichts darüber in dem Code, den Sie gezeigt haben ... irgendwelche Ideen, wo das passiert ist?

EDIT: Ich habe den Unterschied erkannt - und ich bin töricht dafür, das vorher nicht zu tun. Sie wollen den Vorsprung zwingen, im Prozess zu tun:

returnData.Options = this.ProductOptions 
         .AsEnumerable() 
         .Select(o => o.ToDataModel()) 
         .ToList(); 

Diese zusätzliche Aufruf AsEnumerable bedeutet, wird es die Enumerable.Select Überlastung sein, die aufgerufen werden, es entspricht Ihren ursprünglichen Code zu machen.

+0

@Jon SKeet - Danke für die Antwort. Das Hinzufügen der .ToList() - Ergebnisse führt zu demselben Fehler. (Gerade auf dieser Linie jetzt anstatt auf der VIEW) – LiamB

+0

@ Jon Skeet - Sneeky Verdacht, dass dies mit SubSonic zu tun hat. Da ich eigentlich keinen Aufruf an .First() mache; – LiamB

+0

@Pino: Ich habe eine andere Idee. Editing now ... –

0
this.ProductOptions.Select(o => o.ToDataModel()).ToList<ProductOptionModel>(); 
+0

Gleiches Problem bei Verwendung der Beispielzeile. – LiamB

-1

Ich glaube, Sie für die Länge der this.ProductOptions vor der LINQ-Anweisung zu überprüfen.

Also vielleicht (für null ohne Prüfung revidiert):

returnData.Options = (this.ProductOptions.Length > 0) ? this.ProductOptions.Select(o => o.ToDataModel()) : new List<ProductOptionModel>().AsEnumerable(); 
+0

Warum funktioniert die Schleife dann? – LiamB

+0

Vielleicht keine Notwendigkeit, auf Null zu überprüfen. Die Schleife funktioniert, weil bei der Länge 0 der Programmablauf niemals in die Schleife eintritt. –

+0

Die Auswahl sollte nicht fehlschlagen, wenn sie keine Werte erhält. Sie sollte nur ein leeres Ergebnis liefern. –

2

Wie ich sagte, Sie Erste Methode verwenden. Möglicherweise möchten Sie es in FirstOrDefault ändern. es wird gelöst werden. oder können Sie ändern?

Stack Trace

bei System.Linq.Enumerable.Erste

+0

wie gesagt, ich rufe das nicht direkt an. Dies scheint tief in den Unterschalldateien zu liegen. Vielleicht verursacht das das Problem? – LiamB

+0

ja. Warum passiert das? bearbeiten. vielleicht mit try catch statements das beheben. Hast du es versucht? – cem

+0

siehe Jon Skeets Answer. – LiamB