LINQ-запрос к списку пар Bool + String. Как соединить строки без foreach? - PullRequest
4 голосов
/ 20 декабря 2011

есть сомнения относительно запросов LINQ к объектам ...

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

Если какие-либо флаги активны, я хочу записать их в консоль.(Я хочу, чтобы все помеченные контрольные точки были в одной строке, поэтому, возможно, я смогу позже изменить код, чтобы выдать исключение.)Моя проблема заключается в необходимости запуска для каждого из результатов запроса LINQ (который, я думаю, IEnumerable<Filter>) для извлечения строк.Если я уже выполнил запрос (т. Е. Прошел по всему коду), зачем мне «снова запускать»?Похоже, это ужасно масштабируется и не очень элегантно ... Есть мысли?

Ответы [ 6 ]

2 голосов
/ 20 декабря 2011
string fpoint=query.Aggregate((c, c1) => c + System.Environment.NewLine+ c1 );
2 голосов
/ 20 декабря 2011

Поскольку dasblinkenlight и Daev уже упоминали об отложенной части выполнения, я подумал, что вам будет интересно узнать, что вы можете объединять строки без foreach, заменяя

foreach(string fp in query)
{ fpoints = fpoints + fp + System.Environment.NewLine; }

с

string.Join(Environment.NewLine, query)
2 голосов
/ 20 декабря 2011

Вызов var query = filters.Where(f => f.flag).Select(f => f.desc); не запускает запрос.IEnumerable<Filter>, возвращаемое цепочкой вызовов, не собирает Filter объекты, пока вы не перечислите результаты возврата в цикле foreach.

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

var queryResults = filters.Where(f => f.flag).Select(f => f.desc).ToList();
1 голос
/ 20 декабря 2011

Если вы хотите избавиться от своего foreach, вот что-то глупое, что вы можете попробовать.

string.Join(Environment.NewLine, query.ToArray());

Извинения, если я не прочитал ваш вопрос достаточно близко

1 голос
/ 20 декабря 2011

Ваша переменная query является выражением и не будет оцениваться до тех пор, пока она не будет перечислена (в вашем случае foreach).Если вы проанализируете query с помощью отладчика, вы не увидите его содержимое в виде набора Filter, а скорее запрос для получения ваших результатов.Это называется «отложенное выполнение» и довольно хорошо описано в этом блоге (хотя это Linq-SQL, применяются те же принципы).

0 голосов
/ 20 декабря 2011

Что вам нужно, так это функция LINQ, называемая агрегатом. Он объединит элементы списка в один вывод.

Быстрый гугл показывает этот постпакетный поток, показывающий, как использовать функцию агрегирования: Функция агрегирования Linq

Простой пример использования функции приведен здесь: http://blueonionsoftware.com/blog.aspx?p=509fa3f8-c125-4e61-9227-8ca4c4e29210. В этом примере используются запятые, где вместо этого можно использовать новые строки.

...