2010-05-25 2 views
6

Хорошо, у меня есть следующие, настройки и работающие отлично. Эти строки кода должны преобразовывать из DAL Entity (Subsonic) в ViewModel.Loop to LINQ Conversion -

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

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

    returnData.Options = OptionsRetData.AsEnumerable(); 

Я хотел бы преобразовать это в однострочное заявление LINQ и придумал следующее.

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

и получен следующий погрешность.

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

Так почему же первый Постулаты работу, но не LINQ, и какие шаги можно предпринять, чтобы решить ее.

Трассировка стека

на System.Linq.Enumerable.First [TSource] (IEnumerable 1 source, Func 2 предиката) при SubSonic.Extensions.Database.Load [T] (IDataReader РДР, Т ст, Список 1 ColumnNames) at SubSonic.Extensions.Database.ToEnumerable[T](IDataReader rdr, List 1 ColumnNames) в 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()

Может быть, это связано с дозвуковой?

+2

Что такое стек вызовов исключения? – SLaks

+0

Каков тип возврата ToDataModel()? –

+0

@Dave Swersky - Тип возврата - ProductOptionModel – LiamB

ответ

7

Одна из возможностей заключается в том, что она не работает, потому что вы изменили время, в течение которого выполняется запрос. Вместо этого измените код:

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

Это заставит запрос оцениваться одновременно с тем, что было раньше.

EDIT: Ваша трассировка стека показывает First() так или иначе, но мы ничего не получили об этом в коде, который вы показали ... какие-либо идеи, где это происходит?

EDIT: Я понял разницу - и я глуп, потому что раньше этого не делал. Вы хотите, чтобы заставить выступ быть сделано в процессе:

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

Это дополнительный вызов AsEnumerable означает это будет Enumerable.Select перегрузкой, которая вызывается, что делает его эквивалентно исходный код.

+0

@Jon SKeet - Спасибо за ответ. Добавление результатов .ToList() приводит к той же ошибке. (Только на этой линии сейчас, а не на VIEW) – LiamB

+0

@Jon Skeet - Sneeky подозрительно, что это связано с SubSonic. Поскольку я не делаю никакого фактического вызова .First(); – LiamB

+0

@Pino: У меня есть другая идея. Редактирование сейчас ... –

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

Такая же проблема при использовании строки примера. – LiamB

-1

Я думаю, что вы должны проверить длину this.ProductOptions перед оператором LINQ.

Так может быть (пересмотренный без проверки на нуль):

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

Почему цикл работает? – LiamB

+0

Возможно, нет необходимости проверять значение null. Цикл работает, потому что с длиной 0 поток программы никогда не входит в цикл. –

+0

Выбор не должен прерываться, если он не получает никаких значений, хотя ... он должен просто дать пустой результат. –

2

Как я сказал, что вы используете первый метод. вы можете изменить его на FirstOrDefault. он будет решен. или Вы можете изменить?

Трассировка стека

на System.Linq.Enumerable.Первый

+0

как я уже сказал, я не называю это прямо. Это, кажется, глубоко в дозвуковых файлах. Может быть, это вызывает проблему? – LiamB

+0

yep. почему это происходит. редактировать. возможно, используя try catch statements'll исправить это. Вы пробовали? – cem

+0

см. Jon Skeets Answer. – LiamB