2010-05-25 13 views
6

Ok Tengo lo siguiente, la configuración y el funcionamiento excelente. Estas líneas de código deben hacer una conversión de Entidad DAL (subsónica) a un modelo de vista.Conversión a Loop to LINQ -

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

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

    returnData.Options = OptionsRetData.AsEnumerable(); 

me gustaría convertir esto en una sola línea DECLARACIÓN LINQ y se le ocurrió la siguiente.

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

y recibo el siguiente error.

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

Entonces, ¿por qué funciona la primera declaración pero no el LINQ y qué pasos puedo tomar para resolverla?

Seguimiento de la pila

en System.Linq.Enumerable.First [TSource] (IEnumerable 1 source, Func 2 predicado) en SubSonic.Extensions.Database.Load [T] (IDataReader rdr, punto T, Lista 1 ColumnNames) at SubSonic.Extensions.Database.ToEnumerable[T](IDataReader rdr, List 1 columnnames) en 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()

Tal vez esto tiene que ver con subsónico?

+2

¿Cuál es la pila de llamadas de la excepción? – SLaks

+0

¿Cuál es el tipo de devolución de ToDataModel()? –

+0

@Dave Swersky - El tipo de devolución es ProductOptionModel – LiamB

Respuesta

7

Una posibilidad es que no funciona porque ha cambiado el momento en que se materializa la consulta. Cambie el código a esto en su lugar:

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

Esto forzará que la consulta se evalúe al mismo tiempo que antes.

EDITAR: El seguimiento de su pila muestra que First() se llama de alguna manera, pero no hemos encontrado nada al respecto en el código que ha mostrado ... ¿Alguna idea de dónde está sucediendo eso?

EDIT: Me he dado cuenta de la diferencia, y soy una tonta por no haberlo hecho antes. Desea forzar la proyección que hacer en proceso:

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

Esa llamada extra para AsEnumerable significa que va a ser la sobrecarga de Enumerable.Select la que es llamada, por lo que es equivalente a su código original.

+0

@Jon SKeet - Gracias por la respuesta. Agregar los resultados de .ToList() en el mismo error. (Justo en esa línea ahora en lugar de en la vista) – LiamB

+0

@Jon Skeet - Sneeky sospecha de que esto tiene que ver con SubSonic. Como no realizo ninguna llamada real a .Primero(); – LiamB

+0

@Pino: Tengo otra idea. Editando ahora ... –

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

Mismo problema al usar la línea de ejemplo. – LiamB

-1

Yo creo que hay que comprobar si la longitud de this.ProductOptions antes de la declaración de LINQ.

Así que tal vez (revisado sin comprobar NULL):

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

¿Por qué funciona el bucle? – LiamB

+0

Tal vez no sea necesario comprobar si hay nulo. El bucle funciona porque con la longitud 0, el flujo del programa nunca ingresa al bucle. –

+0

Select no debería fallar si no obtiene ningún valor ... solo debería arrojar un resultado vacío. –

2

Como ya he dicho que está utilizando Primer método. es posible que desee cambiarlo a FirstOrDefault. será resuelto o ¿puedes cambiar?

Seguimiento de la pila

en System.Linq.Enumerable.Primero

+0

como dije, no estoy llamando directamente eso. Esto parece ser profundo en los archivos subsónicos. Tal vez eso está causando el problema? – LiamB

+0

sí. es por eso que esto sucede. editar. tal vez el uso de declaraciones try catch arreglará esto. lo has intentado? – cem

+0

ver respuesta de Jon Skeets. – LiamB