Проецирование наборов результатов EF на сложную объектную модель происходит медленно - PullRequest
0 голосов
/ 23 апреля 2020

Я выполняю несколько запросов в 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(); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...