2010-10-22 3 views
5

Я пытаюсь сформулировать запрос LINQ, чтобы выбрать подсписок списка, где он встречает где условие так:LINQ Cast перечислимых в список определенного типа

List<Entities.Base> bases = this.GetAllBases(); 
List<Entities.Base> thebases = from aBase in bases 
           where aBase.OfficeCD == officeCD 
           select aBase; 

где Base это просто класс Entity:

public string BaseCD { get; set; } 
     public string BaseName { get; set; } 
     public string OfficeCD { get; set; } 
     public DateTime EffectiveDate { get; set; } 
     public DateTime ExpirationDate { get; set; } 

Я получаю сообщение об ошибке «не удается преобразовать тип неявно System.Collections.Generic.IEnumerable в System.Collections.Generic.List

Так что я пытался применить оператор Cast, но это не удается. Теперь я вижу, что я не пытаюсь преобразовать тип элемента. Как я могу решить эту проблему? Благодаря!

ответ

10

Это не проблема, которая может быть решена путем «литья»; результат запроса, который вы получили, не является списком - это отложенная последовательность, которая будет передавать соответствующие элементы из по запросу. Вам нужно будет фактически загрузить эти результаты в List<T> для достижения своей цели. Например, метод Enumerable.ToList создаст новый список, заполнит его результатами запроса и затем вернет его.

Несколько вариантов:

var thebases = (from aBase in bases 
       where aBase.OfficeCD == officeCD 
       select aBase).ToList(); 

// fluent syntax 
var thebases = bases.Where(aBase => aBase.OfficeCD == officeCD) 
        .ToList(); 

// not a LINQ method - an instance method on List<T>. 
// Executes immediately - returns a List<T> rather than a lazy sequence 
var thebases = bases.FindAll(aBase => aBase.OfficeCD == officeCD); 

// "manual" ToList() 
var theBases = new List<Entities.Base>(); 
var matchingBases = from aBase in bases 
        where aBase.OfficeCD == officeCD 
        select aBase; 

foreach(var matchingBase in matchingBases) 
    theBases.Add(matchingBase); 
+0

Спасибо! Я только что подумал о чем-то - о том, что он исполнен. Эти запросы не будут выполняться до тех пор, пока они не будут перечислены. Я создаю их в DataLayer, который возвращает запросы. Предположим, что я выбираю ваш первый и имеет: public List GetBasesForFieldOfficeCD (string officeCD) {List databases = this.GetAllBases(); Список thebases = (из базы данных в базах, где aBase.OfficeCD == officeCD выбирает aBase) .ToList(); возвращать базы; } - Нужно ли перечислять/выполнять запросы перед возвратом? –

+0

'ToList()' будет делать перечисление для вас. Конечный результат: «нормальная» структура данных, а не запрос. В принципе, список не помнит, как он был создан. С другой стороны, вы можете * предпочесть *, чтобы ваш метод GetBasesForFieldOfficeCD возвращал вместо этого отложенный запрос. В этом случае сделайте возвращаемый тип «IEnumerable » и удалите вызов 'ToList()'. – Ani

2

В дополнение к методу @Ani упоминалось, вы можете также использовать LINQ для выбора данных непосредственно в классы, как это:

List<Entities.Base> bases = this.GetAllBases(); 
List<Entities.Base> thebases = new List<Entities.Base>(
          from aBase in bases 
          where aBase.OfficeCD == officeCD 
          select new Entities.Base { 
           BaseCD = aBase.BaseCD, 
           BaseName = aBase.BaseName, 
           OfficeCD = aBase.OfficeCD, 
           EffectiveDate = aBase.EffectiveDate, 
           ExpirationDate = aBase.ExpirationDate 

         }; 
+0

Я не думаю, что он хочет «выбрать новый Entities.Base», потому что он создает все новые объекты с тем же содержимым, что и старые объекты. Скорее всего, он хочет, чтобы одни и те же объекты заполняли оба списка. – Gabe

+0

@Gabe - Возможно. Я согласен с ответом Ани (отсюда и на кредит), но хотел бы предложить другой вариант для рассмотрения. –

1

Вот вариант на Joel's answer, который повторно использует исходные объекты для нового списка вместо их клонирования:

List<Entities.Base> bases = this.GetAllBases(); 
List<Entities.Base> thebases = new List<Entities.Base>( 
          from aBase in bases 
          where aBase.OfficeCD == officeCD 
          select aBase); 
Смежные вопросы