Могу ли я использовать linq для удаления элементов из asp .net DropDownList.Items?

Как сказано в заголовке, можно ли использовать LINQ для удаления элементов из .Items DropDownList, где элемент не равен указанным мной строкам?

Другими словами, у меня есть список строк, если элемент не соответствует ни одной строке в списке, он удаляется.

ПРИМЕЧАНИЕ. Я знаю, как этого добиться, я могу сделать это с помощью цикла foreach. Это нормально, но я хочу знать, есть ли альтернатива LINQ.

РЕДАКТИРОВАТЬ: Я должен сказать - свойство элемента .Text соответствует любому элементу в списке строк.

РЕДАКТИРОВАТЬ: Для тех, кто заинтересован, это был предложенный мной способ foreach:

        private void FilterDropDownChoices(List<String> permittedChoices)
        {
            foreach(ListItem item in ddlChoices.Items)
            {
                if (!permittedChoices.Contains(item.Text))
                {
                    ddlChoices.Items.Remove(item);
                }
            }
        }

person Community    schedule 25.07.2012    source источник
comment
Вы это проверяли? На самом деле вы должны получить ошибку с этим кодом, потому что вы не можете изменить коллекцию во время итерации по ней.   -  person ryanulit    schedule 25.07.2012
comment
Я не тестировал его, нет, он был скомпонован очень быстро, так как я жду эту альтернативу linq. Учитывая ту ошибку, которую вы только что упомянули - я получу и установлю коллекцию элементов вне foreach (используйте другую локальную коллекцию), если нет предлагаемой альтернативы LINQ. Спасибо @ryanulit.   -  person    schedule 25.07.2012
comment
У вас есть цикл foreach, который используется для того, чтобы вызывать побочные эффекты (изменять коллекцию Items). Linq не заменяет это. Linq предназначен для запросов, чего вы не делаете. Дополнительная литература. Лучшее, что вы могли сделать, - это получить набор элементов для удаления через LINQ. Тем не менее, вы все равно захотите иметь foreach цикл для их удаления.   -  person Servy    schedule 25.07.2012
comment
Любопытство: зачем вам нужен LINQ?   -  person hometoast    schedule 25.07.2012


Ответы (3)


ryanulit на самом деле дал лучший ответ.

Проблема в том, что ListItemCollection реализует только интерфейс IEnumerable. Расширения LINQ работают с IEnumerable ‹T›. Следовательно, приведение (IEnumerable) к (IEnumerable ‹T›) - теперь вы можете использовать LINQ.

Итак, чтобы ответить на ваш вопрос:

ddlChoices.Items
.Cast<ListItem>()
.Where(item => !permittedChoices.Contains(item.Text))
.ToList()
.ForEach(ddlChoices.Items.Remove);

Вы должны использовать ToList () или ToArray () или аналогичный, потому что вы не можете изменять коллекцию при чтении из нее - ToList () копирует ссылки на выбранные элементы, которые затем могут быть зациклены и удалены из ListItemCollection.

Во время написания я увидел комментарий Маттена - он выделил полезную функциональность ListItemCollection (возможность удалять элементы по их текстовому свойству), но неправильно понял вопрос. Требование было таким: вы можете иметь «allowedChoices» только внутри ddlChoices.Items. В примере Мэттена удаляются действительные варианты выбора и остаются недействительные, что противоположно тому, что он просил.

person Shelakel    schedule 25.07.2012

LINQ - это язык запросов, он не используется для изменения ваших данных. что вы можете сделать, он запросит ваш список элементов для желаемого состояния и затем произведет сбор самостоятельно.

образец:

var relevant = from item in list.Items
               where permittedChoices.Contains(item.ToString())
               select item

а затем вы можете очистить список элементов и добавить только то, что вам нужно.

ddlChoices.Clear();
ddlChoices.AddRange(relevant.ToArray());
person Tamir    schedule 25.07.2012

Просто использовать linq? Ну вот :-)

private static void FilterDropDownChoices(List<String> permittedChoices)
{
    ddlChoices.Items.Cast<ListItem>()
       .Where(li => permittedChoices.Contains(li.Text))
       .ToList()
       .ForEach(ddlChoices.Items.Remove);
}
person Matten    schedule 25.07.2012