Я выполняю несколько запросов в EF 6 (последний пакет найден в NuGet) и обнаружил, что когда я проецирую (IQueryable<T>.Select(...)
) набор результатов на довольно сложную объектную модель, время выполнения проекции (раздувание) результаты в. NET объекты - не SQL время выполнения) очень медленные.
Это ожидаемое поведение и есть ли обходной путь?
Для еще раз, я решил, что выполнение запроса на сервере SQL является приемлемо быстрым. Я также определил, что сетевой ввод-вывод приемлемо быстр. Я также заметил, что EF очень быстро создает запрос SQL из IQueryable. Похоже, что проецирование набора результатов является самой медленной частью всей деятельности, занимая от 5 до 7 секунд для набора результатов всего из нескольких строк.
Я еще больше выделил проблему нескольким членам модель, на которую я проецирую. Трое из них IEnumerables<int>
, а четвертый IEnumerable<SomeObject>
. SomeObject
очень прост, содержит только два опубликованных c примитивных члена и ничего больше.
Дальнейшее тестирование показывает, что удаление любого из этих 4 членов из моей проекции уменьшает время выполнения на секунду или две каждый, что я считаю еще одним подтверждением того, что проецирование на объект, состоящий из коллекций, является root причиной моего замедления.
Вот конкретный пример того, что я пытаюсь сделать.
public class MyBusinessObject {
public int SomeMember {get;set;}
public double SomeOtherMember {get;set;}
//more primitive members here
public IEnumerable<int> MyList {get;set;}
//more collections here
}
//query is dynamically generated and will be considerably more complicated than this...
//...(more joins and inner selects), but it's bounded, and the runtime is acceptable to me
IQueryable<MyDbSetEntity> query = myContext.MyDbSet.Join(...).Where(...).OrderBy(...).Skip(...).Take(...).AsNoTracking();
IQueryable<MyBusinessObject> model = query.Select(myEntity => new MyBusinessObject {
SomeMember = myEntity.SomeMember,
SomeOtherMember = myEntity.SomeOtherMember,
MyList = myEntity.MyList
});
//this is the line that takes forever - i have determined that walking the expression tree,...
//...generating the sql, running the sql, returing the data over the wire are all not implicated...
//...in the majority of the time spent with maybe a second spent on all of the aforementioned,...
//...and the remaining 5 or seconds spent building the list of objects.
List<MyBusinessObject> objects = model.ToList();