Зависит от LINQ
Хорошо, чем больше я использую LINQ, тем больше мне это нравится! Недавно я обнаружил, что работаю над некоторым устаревшим кодом. Это ваше классическое приложение DataSet и DataTable. Ну, добавив немного функциональности, я обнаружил, что действительно хочу просто запросить строки DataTable для результатов, которые я искал.
Позвольте мне повторить, что... вместо того, чтобы зацикливаться и добавлять в коллекцию temp, я просто хотел спросить коллекцию Rows, что мне нужно. Нет циклов, никаких временных переменных, просто дайте мне то, что я хочу.
var customerOrderIds = table.Rows.Cast<DataRow>()
.Where(x => (string)x["CUSTOMER_ID"] == customerId)
.Select(x => (string)x["CUSTOMER_ORDER_ID"])
.Distinct();
Мой вопрос в том, хорошо ли это или нет, или увлекаюсь LINQ? Мне кажется, что этот декларативный стиль вытаскивания подмножества данных из коллекции хорошая вещь и более читаемая в конце. Но опять же, может быть, меня просто поразило:)
Ответы
Ответ 1
Еще одно наблюдение; если вы не используете типизированные наборы данных, вы также можете узнать о методе расширения 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)
Ответ 2
Мне кажется хорошо, хотя я бы попытался использовать сильно типизированный набор данных, который делает запросы LINQ еще более приятными.
Но да, LINQ - очень хорошая вещь - и LINQ to Objects (и окружающие технологии для XML и DataSets) невероятно предсказуемы по сравнению с поставщиками LINQ из-за процесса. (Он менее сексуальный, чем LINQ to SQL, но более широко применимый IMO.)
Ответ 3
Запрос выглядит нормально.
Я хотел бы указать на две мелочи.
Нет циклов
System.Linq.Enumerable методы работают против контракта IEnumerable (T), который почти всегда означает looping-O (N) -решения. Два значения этого:
- Предпочитает Any() over Count() > 0. Любой() есть O (1). Count() - O (N).
- Присоединиться... все соединения - это вложенный цикл O (M * N).
.Cast
.Cast отлично работает для DataTable.Rows(все эти объекты - это строки, поэтому приведение всегда выполняется успешно). Для гетерогенных коллекций помните .OfType() - который отфильтровывает любые элементы, которые нельзя выполнить.
Наконец, имейте в виду, что запросы не выполняются до тех пор, пока они не будут перечислены! Вы можете принудительно перечислять foreach, ToList, ToArray, First, Single и многие другие.
Ответ 4
Лично, поскольку таблица данных не имеет возможности самостоятельно выполнять выделение, я скажу, что это не так уж плохо.
Я мог бы спросить, хотя бы какой-то способ в конечном итоге перейти к использованию объектов, а не таблиц данных, так как я думаю, что будущим разработчикам будет легче понять.
Ответ 5
Ты не увлекаешься вообще. Есть фактические работы, опубликованные в LINQ to DataSets. Наличие таких четких, декларативных запросов объектов позволяет значительно упростить работу кода. Но вы должны помнить, что в то время, когда вы фильтруете данные, все это уже было отброшено. Вы можете захотеть добавить фильтрацию в SQL для запроса DataSet.
Ответ 6
LINQ просто записывает для вас код "looping/temp variable". LINQ помогает быстрее писать код (и более читаемым).
Вы хороший код.
Ответ 7
Соединение (используя ключевое слово join, но не ключевое слово from) использует словарь для совпадений и, таким образом, O(M+N)
.
Итак, это группа, но не следующее:
from x in Xs
from y in Ys
.Where(o => o == x)
select new
{
x,
y
}
который равен O(M*N)
.