2013-03-21 4 views
1

У меня есть следующий фрагмент кода:Получение одного результата из заявления LINQ

private void SelectRowData(int wire, int bond, string svid) 
{ 
    var results = from myRow in PPLoadedData.AsEnumerable() 
        where 
         myRow.Field<Int32>("Wires.OperationOrder") == wire && 
         myRow.Field<Int32>("Bonds.OperationOrder") == bond 
        select myRow[svid]; 
} 

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

Я ищу что-то, где я могу получить доступ к данным.

Вот что отладчик говорит:

Имя:. (новый System.Linq.SystemCore_EnumerableDebugView (результаты)) Items [0]

Значение: 700,0

Тип: объект {двухместный}

PPLoadedData является DataTable.

Заранее спасибо.

+0

Вы имели в виду 'результаты' от вашего метода? – jhewlett

ответ

7

Если вы ожидаете, что запрос приведет к одного элемента, вы должны использовать метод SingleOrDefault следующим образом:

var result = (from myRow in PPLoadedData.AsEnumerable() 
       where myRow.Field<Int32>("Wires.OperationOrder") == wire && 
        myRow.Field<Int32>("Bonds.OperationOrder") == bond 
       select myRow[svid]).SingleOrDefault(); 
if(result != null) 
    // Do stuff with result 

В общем, запросы Linq возвращают IEnumerables, которые вы должны перебирать, а не доступ по индексу. Однако в случае, когда требуется только одно значение, существует несколько способов получить требуемое значение. Обратитесь к System.Linq.Enumerable на MSDN за дополнительной информацией.

Редактировать: Обязательно прочтите ответ Эрика, в котором объясняется, когда использовать этот метод для получения индивидуального результата.

+0

У меня нет опции для FirstOrDefualt(). Однако повторение работы над сборником работало, как указано ниже. Опять же, результирующий набор должен быть только одним значением, и я чувствую, что цикл за 1 элемент является плохим решением. Итак, есть ли у вас какая-либо другая информация/пример того, как я могу это сделать? Еще раз спасибо Редактировать править. Не нужен ли DataTable AsEnumerable? –

+0

@SeanP У вас есть 'использование оператора System.Linq;' в вашем файле кода? –

+0

Я этого не делал. Вау, какой надзор. Благодарю. Ive закодировал мое решение! –

2

результат - тип коллекции. вам нужно перебрать его Datatable.AsEnumerable. Когда результат типа IEneumerable<T> и другие, которые LINQ возвращает в коллекции, вам нужно перебирать как этот

foreach (var item in results) 
{ 
    //do some thing with item 
} 
+0

Спасибо, Это действительно работало, но цикл за 1 элемент не является хорошей практикой. У вас есть что-нибудь еще, что вы могли бы предложить? благодарю вас за комментарий. –

+0

Вам не нужно перебирать IList , так как он определяет индексатор.Я также не знаю о какой-либо функции LINQ, которая возвращает IList ... –

12

Чтобы уточнить ответ Джейсона:

  • Если коллекция может иметь любое количество элементов, используйте FirstOrDefault().
  • Если в коллекции всегда есть один или несколько предметов, используйте First().
  • Если в коллекции всегда есть ноль или один элемент, используйте SingleOrDefault().
  • Если у коллекции всегда есть один предмет, используйте Single().

Если вы используете соответствующий метод, вы получаете исключение, когда ваш инвариант нарушен, что поможет вам отладить программу.

Смежные вопросы