Loop to LINQ Conversion -
Ok I have the following, set-up and working great. These lines of code should do a conversion from DAL Entity (Subsonic) to a ViewModel.
IList<ProductOptionModel> OptionsRetData = new 开发者_运维问答List<ProductOptionModel>();
foreach (var CurProductOption in this.ProductOptions)
{
OptionsRetData.Add(CurProductOption.ToDataModel());
}
returnData.Options = OptionsRetData.AsEnumerable();
I'd like to convert this to a LINQ single line statment and came up with the following.
returnData.Options = this.ProductOptions.Select(o => o.ToDataModel());
and am recieving the following error.
Server Error in '/' Application.
Sequence contains no matching element
So why does the first statment work but not the LINQ and, what steps can I take to resolve it.
Stack Trace
at System.Linq.Enumerable.First[TSource](IEnumerable
1 source, Func
2 predicate) at SubSonic.Extensions.Database.Load[T](IDataReader rdr, T item, List1 ColumnNames) at SubSonic.Extensions.Database.ToEnumerable[T](IDataReader rdr, List
1 ColumnNames) at SubSonic.Linq.Structure.DbQueryProvider.Execute[T](QueryCommand1 query, Object[] paramValues) at lambda_method(Closure ) at SubSonic.Linq.Structure.DbQueryProvider.Execute(Expression expression) at SubSonic.Linq.Structure.Query
1.GetEnumerator()
Maybe this is to do with subsonic?
One possibility is that it's not working because you've changed the time at which the query is materialized. Change the code to this instead:
returnData.Options = this.ProductOptions.Select(o => o.ToDataModel()).ToList();
That will force the query to be evaluated at the same time it was before.
EDIT: Your stack trace is showing First()
being called somehow, but we haven't got anything about that in the code you've shown... any ideas where that's happening?
EDIT: I've realised the difference - and I'm foolish for not doing so before. You want to force the projection to be done in-process:
returnData.Options = this.ProductOptions
.AsEnumerable()
.Select(o => o.ToDataModel())
.ToList();
That extra call to AsEnumerable
means it'll be the Enumerable.Select
overload which gets called, making it equivalent to your original code.
As i said you're using First method. you may want to change it to FirstOrDefault. it will be solved. or do you able to change?
Stack Trace
at System.Linq.Enumerable.First
this.ProductOptions.Select(o => o.ToDataModel()).ToList<ProductOptionModel>();
I think you have to check for the length of this.ProductOptions before the LINQ statement.
So maybe (revised without check for null):
returnData.Options = (this.ProductOptions.Length > 0) ? this.ProductOptions.Select(o => o.ToDataModel()) : new List<ProductOptionModel>().AsEnumerable();
精彩评论