2014-09-22 2 views
0

Основная часть моего вопроса в заголовке: Does WPF DataGrid Implicitly Convert IEnumerable < X> ItemsSource to List < x>?ли WPF DataGrid неявно преобразовывать IEnumerable <x> в список <x> При привязке?

У меня есть WPF, используя MVVM и т.д. ViewModel свойство определяется как ...

private IEnumerable<Plan> _PlanListItems; 
    public IEnumerable<Plan> PlanListItems 
    { 
     get { return _PlanListItems; } 
     protected set { RaiseAndSetIfChanged(ref _PlanListItems, value); } 
    } 

    // ... 
    // in some method 
    OpenPlanItems = await service.GetAllPlansAsync(); 

В связ ...

public IEnumerable<Plan> GetAllPlans() 
    { 
     using (MyEntities ent = new MyEntities()) 
     { 
      return (from a in ent.DbPlans select a) 
       .AsEnumerable() 
       .Select(o => o.Convert()); // Does some stuff to convert DbPlan entity into Plan class 
     } 
    } 

    public async Task<IEnumerable<Plan>> GetAllPlansAsync() 
    { 
     return await Task.Run(() => GetAllPlans()); 
    } 

В XAML ...

<DataGrid ItemsSource="{Binding PlanListItems}" ...> 

Это генерирует исключение: операция не может быть выполнена, поскольку ошибка DbContext была устранена. Another question указывает, что причиной может быть из-за позднего выполнения объекта IEnumerable (т. Е. Попытки перечислить после того, как контекст был удален).

Кроме того, у меня есть аналогичный код, который имеет преобразование .ToList() внутри метода, аналогичного GetAllPlans(). Нечто подобное, но не фактический код:

public List<Plan> GetAllPlans() 
    { 
     using (MyEntities ent = new MyEntities()) 
     { 
      return (from a in ent.DbPlans select a) 
       .AsEnumerable() 
       .Select(o => o.Convert()).ToList(); // Does some stuff to convert ... 
     } 
    } 

Он оказался медленный метод (> 5 секунд). Когда я удалил преобразование .ToList(), он опустил время до < 0,2 секунды, но неэффективность вернулась (и почти такая же продолжительность), когда я привязываю результат к DataGrid.

Это заставляет меня думать, что WPF DataGrid неявно преобразует связанные элементы IEnumerable в список как часть процесса привязки. Это правда? И если да, существует ли способ избежать неявного преобразования?

+0

сетка данных не выполняет такие преобразования, она просто пытается перечислить данные, используя соответствующий просмотр коллекции. – pushpraj

+0

Umm .. это больше похоже на заполнение IEnumerable при привязке. – bit

+0

AFAIK DataGrid будет ** не ** конвертировать 'IEnumerable ' в 'Список '. – Sandesh

ответ

0

Причина, по которой ваш IEnumerable<T> занимает < 0,2 секунды, чтобы вернуть это потому, что она фактически не возвращает данные: она возвращает больше «как получить данные, когда вы действительно заинтересованы в этом». Это только даст вам данные, когда вы перебираете их или иным образом получаете к нему доступ. Это даст вам ошибку DbContext has been disposed of, если бы клиентский код попытался использовать это «как получить данные» вне сферы контекста.

Именно поэтому, когда у вас есть .ToList() на ваше обслуживание, это занимает больше времени: потому что это фактически, возвращающее данные. Реальные данные, которые вы действительно можете использовать на клиенте, не беспокоясь о масштабах контекста.

DataGrid просто нуждается в его коллекции ItemsSource, чтобы реализовать интерфейс IEnumerable, чтобы он мог перечислить элементы по мере необходимости. Это не «преобразование вещей в список» как таковое, а просто перечисление коллекции.

Смежные вопросы