Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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](IEnumerable1 source, Func2 predicate) at SubSonic.Extensions.Database.Load[T](IDataReader rdr, T item, List1 ColumnNames) at SubSonic.Extensions.Database.ToEnumerable[T](IDataReader rdr, List1 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.Query1.GetEnumerator()

Maybe this is to do with subsonic?

like image 680
LiamB Avatar asked May 25 '10 15:05

LiamB


People also ask

Is LINQ only for C#?

LINQ (Language Integrated Query) is uniform query syntax in C# and VB.NET to retrieve data from different sources and formats. It is integrated in C# or VB, thereby eliminating the mismatch between programming languages and databases, as well as providing a single querying interface for different types of data sources.

Which one is faster for or foreach in C#?

As you can see, using for is around 2-3 times faster than foreach!


1 Answers

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.

like image 152
Jon Skeet Avatar answered Oct 13 '22 01:10

Jon Skeet