Как ускорить загрузку данных с помощью асинхронного метода в EF? - PullRequest
0 голосов
/ 15 мая 2019

Пока у меня много данных для загрузки в моем списке.Когда я использовал обычный (синхронный) способ загрузки данных, это было около 20 секунд, чтобы загрузить все данные.Я сделал этот асинхронный метод, и теперь мне нужно около 7 секунд для загрузки.Интересно, есть ли способ ускорить его, например, загрузить первые 20 карт, как только откроется экран, а затем все остальное?Это мой код до сих пор ..

public async Task<List<CardObject>> GetCardsAsync()
{
    using (var context = new MyCARDEntities())
    {
        return await context.Card
            .Include(f => f.Person)
            .Include(k => k.CardType)
            .Where(arg => arg.LastAction != "D" && arg.PERSON_ID != null)
            .Select(k => new CardObject()
            {
                    Id = k.Id,
                    UID = k.UID,
                    Person = new PersonBasicObject()
                    {
                        Id = k.PersonBasicObject.Id,
                        OIB = k.PersonBasicObject.OIB,
                        Name = k.PersonBasicObject.Name,
                        LastName = k.PersonBasicObject.LastName
                    }
            })
            .ToListAsync();
    }
}

, и это в viewModel

private async void LoadCards()
{
    var cards = await repKartica.GetCardsAsync();
    CardLst = new ObservableCollection<CardObject>(cards);
}

private ObservableCollection<CardObject> _CardLst;
public ObservableCollection<CardObject> CardLst 
{
    get => _CardLst;
    set
    {
        _CardLst= value;
        RaisePropertyChanged(() => CardLst);
    }
}

1 Ответ

0 голосов
/ 16 мая 2019

Создание метода async не делает метод быстрее, он просто позволяет методу сдать исполняющий поток, чтобы позволить другому коду работать. Это может сделать код более отзывчивым, но не ускорит получение этих данных.

Во-первых, загрузка большого количества данных не очень хорошая идея, если ее можно избежать. Нужно ли клиентам видеть всех этих данных одновременно или они / могут быть разбиты на страницы по 20 карт одновременно? Если это так, или вы можете разбивать их на страницы, то подумайте о том, чтобы использовать коллекцию с разбивкой по страницам, которая может запрашивать определенные страницы данных (используя .Skip() & .Take()), чтобы извлекать только около 20 записей за раз при изменении видимой страницы.

Следующим шагом будет посмотреть на выполняемый запрос. Запустите профилировщик, такой как ExpressProfiler, для вашей базы данных и запишите SQL, выполняемый EF. Выполните копию этих запросов в Enterprise Manager, чтобы получить план выполнения и посмотреть, есть ли рекомендации по индексам.

Другие советы: При использовании .Select() вам не нужно использовать .Include(). Команда Select создаст запрос для автоматического извлечения из связанных объектов.

Являются ли PersonBasicObject и CardObject вашими определениями сущностей? Если да, сколько полей в этих объектах останется незаполненными этим Select? В идеале вы должны использовать выделенные модели представления, а не передавать объекты. Заполняя сущности, используя Select() для выборочного заполнения данных, вы составляете сущность, которая не является сущностью в том смысле, что она не является полным представлением сущности. Это может быть неэффективно из-за переменных, которые все еще занимают память, но не заполняются, и это вводит в заблуждение и приводит к ошибкам, потому что у вас будет код, который ожидает сущности, и может вызываться / повторно использоваться, но затем иметь дело с «настоящими» полными сущностями по сравнению с неполными объектами, которые были загружены, как это. Единственная цель сущностей должна состоять в том, чтобы представлять состояние данных, а не передавать их в состояние просмотра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...