2014-01-03 2 views
6

Чтение here и here. Я понимаю, что синтаксис запроса и расширения метода в значительной степени являются синтаксической разницей. Но теперь у меня есть структура данных, содержащая данные измерений, и вы хотите определить процентили. Я пишу:Linq Query синтаксис против метода Chain: return type

var ds = (from device in dataSet.devices 
      where !device.paramValues[i].Equals(double.NaN) 
      select device.paramValues[i]).OrderBy(val => val); 
double median = percentile(ds as IOrderedEnumerable<double>, 0.5); 

и все работает нормально. DS имеет тип System.Linq.OrderedEnumerable<double,double>

Что меня смущает, чтобы написать все это в синтаксисе запроса:

var ds = (from device in dataSet.devices 
      where !device.paramValues[i].Equals(double.NaN) 
      orderby device.paramValues[i] 
      select device.paramValues[i]); 
double median = percentile(ds as IOrderedEnumerable<double>, 0.5); 

Теперь, DS имеет тип System.Linq.Enumerable.WhereSelectEnumerableIterator<Dataset.DeviceData,double> и вызов функции процентиля не удается.

Не уверен, что мне здесь не хватает ... - нет основополагающей причины, почему я предпочел бы второй синтаксис, но я хотел бы понять разницу ... Спасибо за вашу помощь!

+0

Это не совсем тот же код (не DataSet), но она работает http://share.linqpad.net/kn55tw.linq –

+0

@Peri - ТНХ; Дело в том, что 'percentile' ожидает IOrderedEnumerable. С IEnumerable я подтверждаю, что он тоже работает здесь ... –

+0

Почему «процентиль» должен знать, что этот параметр является «IOrderedEnumerable»? По большому счету, Linq структурирован таким образом, что некоторая связь не нужна. Фактически единственный метод, уникальный для IOrderedEnumerable, который я вижу в документации, - это «CreateOrderedEnumerable», функциональность которого может быть достигнута с помощью методов расширения 'ThenBy' и/или' ThenByDescending'. –

ответ

5
from device in dataSet.devices 
where !device.paramValues[i].Equals(double.NaN) 
select device.paramValues[i] 

превращается в методы следующим образом:

dataSet.devices 
     .Where(device => !device.paramValues[i].Equals(double.NaN)) 
     .Select(device => device.paramValues[i]); 

Добавление OrderBy вызова вы получаете

dataSet.devices 
     .Where(device => !device.paramValues[i].Equals(double.NaN)) 
     .Select(device => device.paramValues[i]) 
     .OrderBy(val => val); 

Другой запрос

from device in dataSet.devices 
where !device.paramValues[i].Equals(double.NaN) 
orderby device.paramValues[i] 
select device.paramValues[i]; 

превращается в

dataSet.devices 
     .Where(device => !device.paramValues[i].Equals(double.NaN)) 
     .OrderBy(device => device.paramValues[i]) 
     .Select(device => device.paramValues[i]); 

Как вы можете видеть, это не совсем та же цепочка методов, и это потому, что в результате вы получаете другой объект. Содержимое одного и того же, но возвращаемого типа нет.

2

Посмотрите на другой ответ первым. Вот как сделать то же самое с синтаксисом запросов:

from device in dataSet.devices 
where !device.paramValues[i].Equals(double.NaN) 
select device.paramValues[i] into x //into syntax 
orderby x 
select x; 
Смежные вопросы