2008-11-04 4 views
10

Хорошо, чем больше я использую LINQ, тем больше мне это нравится! Недавно я обнаружил, что работаю над некоторым устаревшим кодом. Это ваше классическое приложение DataSet и DataTable. Ну, добавив немного функциональности, я обнаружил, что действительно хочет просто запросить строки DataTable для результатов, которые я искал.Зависит от LINQ

Позвольте мне повторить, что ... вместо того, чтобы зацикливаться и добавлять в коллекцию temp, я просто хотел спросить коллекцию Rows, что мне нужно. Нет циклов, никаких переменных температуры, просто дайте мне то, что я хочу.

var customerOrderIds = table.Rows.Cast<DataRow>() 
    .Where(x => (string)x["CUSTOMER_ID"] == customerId) 
    .Select(x => (string)x["CUSTOMER_ORDER_ID"]) 
    .Distinct(); 

Мой вопрос, является ли или нет, это хорошая вещь, или я увлекаюсь с LINQ? Мне кажется, что этот декларативный стиль вытаскивания подмножества данных из коллекции является хорошим и более читаемым в конце. Но опять же, может быть, меня просто поразили :)

ответ

12

Еще одно наблюдение; если вы не используете типизированных наборов данных, вы также можете узнать о методе Field<> расширения:

var customerOrderIds = table.Rows.Cast<DataRow>() 
     .Where(x => x.Field<string>("CUSTOMER_ID") == customerId) 
     .Select(x => x.Field<string>("CUSTOMER_ORDER_ID")) 
     .Distinct(); 

Или с помощью синтаксиса запросов:

var customerOrderIds = (
     from row in table.Rows.Cast<DataRow>() 
     where row.Field<string>("CUSTOMER_ID") == customerId 
     select row.Field<string>("CUSTOMER_ORDER_ID") 
    ).Distinct(); 

Я не говорю, что это лучше или хуже - еще один жизнеспособный вариант.

(На самом деле, я не использую DataTable очень много, поэтому YMMV)

+1

Я не знал о Поле <> ... сладкий - вы только что добавили к моей зависимости Я думаю – Rob 2008-11-04 16:04:30

+0

(sfx: безумно проверяет книгу, чтобы узнать, знал ли я об этом в какой-то момент ...) Фу ... удивительно то, что забывается в течение года :) – 2008-11-04 16:11:27

5

Кажется мне хорошо - хотя я бы попытался использовать сильно типизированный набор данных, который делает запросы LINQ еще более приятными.

Но да, LINQ - очень хорошая вещь - и LINQ to Objects (и окружающие технологии для XML и DataSets) сказочно предсказуемы по сравнению с поставщиками LINQ, не использующими процесс. (Это меньше sexy, чем LINQ to SQL, но более широко применимый IMO.)

0

Лично, поскольку таблица данных не имеет возможности самостоятельно выбирать выделение, я скажу, что это не " Все это плохо.

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

0

Вы не увлекаетесь вообще. Есть фактические работы, опубликованные в LINQ to DataSets. Наличие таких четких, декларативных запросов объектов позволяет значительно упростить работу кода. Но вы должны помнить, что в то время, когда вы фильтруете данные, все это уже было отброшено. Вы можете захотеть добавить фильтрацию в SQL для запроса DataSet.

0

LINQ просто писать "зацикливание/переменную Temp" код для вас. LINQ помогает быстрее писать код (и более читаемым).

Вы код хороший.

3

Запрос выглядит хорошо.

Я хотел бы указать на две мелочи.

Нет зацикливания

System.Linq.Enumerable методы не работают по контракту IEnumerable (Т), что почти всегда означает цикл - решения O (N). Два значения этого:

  • Предпочитает Любое() над Count()> 0. Любой() есть O (1). Count() - O (N).
  • Присоединиться ... все соединения представляют собой вложенную петлю O (M * N).

.Cast

.Cast работает отлично подходит для DataTable.Rows (все эти объекты -are- строки, так отданных всегда успевает). Для гетерогенных коллекций помните .OfType() - который отфильтровывает любые элементы, которые нельзя выполнить.

И, наконец, имейте в виду, что запросы не выполняются до тех пор, пока они не будут перечислены! Вы можете принудительно перечислять foreach, ToList, ToArray, First, Single и многое другое.

0

Соединение (с использованием ключевого слова join, но не ключевое слово from) использует словарь для совпадений и, таким образом, O(M+N).

Так группа по, но не следующее:

from x in Xs 
from y in Ys 
    .Where(o => o == x) 
select new 
{ 
    x, 
    y 
} 

который O(M*N).

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