Как преобразовать IEnumerableT в ListT в C #?

17

Я использую LINQ для запроса общего словаря, а затем использую результат как источник данных для моего ListView (WebForms).

Упрощенный код:

Dictionary<Guid, Record> dict = GetAllRecords();
myListView.DataSource = dict.Values.Where(rec => rec.Name == "foo");
myListView.DataBind();

Я думал, что это сработает, но на самом деле оно выдает System.InvalidOperationException :

  

ListView с id 'myListView' должен   имеют источник данных, который либо   реализует ICollection или может выполнять   подкачка источника данных, если AllowPaging   правда.

Чтобы получить работу, мне пришлось прибегнуть к следующему:

Dictionary<Guid, Record> dict = GetAllRecords();
List<Record> searchResults = new List<Record>();

var matches = dict.Values.Where(rec => rec.Name == "foo");
foreach (Record rec in matches)
    searchResults.Add(rec);

myListView.DataSource = searchResults;
myListView.DataBind();

Есть ли в первом примере небольшая ошибка, чтобы заставить ее работать?

(Не был уверен, что использовать в качестве названия вопроса для этого, не стесняйтесь редактировать что-то более подходящее)

    
задан Christian Hagelid 28.08.2008 в 07:21
источник
  • Это противоположность stackoverflow.com/questions/472669/... –  John 04.03.2010 в 16:58

5 ответов

29

Попробуйте следующее:

var matches = dict.Values.Where(rec => rec.Name == "foo").ToList();

Имейте в виду, что это будет по существу создание нового списка из первоначальной коллекции Values, и поэтому любые изменения в вашем словаре не будут автоматически отражаться в вашем связанном контроле.

    
ответ дан Matt Hamilton 28.08.2008 в 07:23
источник
9

Я предпочитаю использовать новый синтаксис Linq:

myListView.DataSource = (
    from rec in GetAllRecords().Values
    where rec.Name == "foo"
    select rec ).ToList();
myListView.DataBind();

Почему вы получаете словарь, когда не используете ключ? Вы платите за эти накладные расходы.

    
ответ дан Keith 28.08.2008 в 13:22
источник
  • @Keith: Я использую ключ Guid в словаре где-то еще в моем коде, поэтому я могу получить запись по идентификатору записи. Согласитесь не согласиться на синтаксис;) –  Christian Hagelid 28.08.2008 в 14:27
  • Подпишитесь для вас. –  fuzz 21.11.2011 в 07:07
3

Вы также можете попробовать:

var matches = new List<Record>(dict.Values.Where(rec => rec.Name == "foo"));

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

    
ответ дан Jon Limjap 28.08.2008 в 08:21
источник
1
myListView.DataSource = (List<Record>) dict.Values.Where(rec => rec.Name == "foo");
    
ответ дан lomaxx 28.08.2008 в 07:23
источник
  • @lomaxx: Ваше первое решение не работает. Кажется, я не могу отдать результат из предложения where в List <Record>. Это приводит к следующему исключению во время выполнения: невозможно лить объект типа «<WhereIterator> d__01 [Record]» для ввода «System.Collections.Generic.List1 [Record]». Ваше второе решение отлично работает, и так же работает Мэтт Хэмилтонс. Я принял [Matt Hamiltons] (stackoverflow.co –  Christian Hagelid 28.08.2008 в 08:27
0

Просто добавляя знания, следующее предложение не восстанавливает никаких данных из db. Просто создайте запрос (для него это тип iqueryable). Для запуска этого запроса вы должны добавить .ToList () или .First () в конец.

dict.Values.Where(rec => rec.Name == "foo")
    
ответ дан Elias MP 08.08.2016 в 13:30
источник