. Net Entity Framework Проверить, существует ли значение в разных таблицах Оптимизация - PullRequest
0 голосов
/ 06 августа 2020

У меня есть следующая функция, которая проверяет, существует ли идентификатор в 4 разных таблицах и возвращает логическое значение:

 public bool CheckIfUsed(int targetId)
        {
            bool isUsedOnTable1 = false;
            bool isUsedOnTable2 = false;
            bool isUsedOnTable3 = false;
            bool isUsedOnTable4 = false;

            isUsedOnTable1 = this.DbContext.table1.Select(target => target.TargetID).Where(TargetID => TargetID == targetId).Count() > 0;
            isUsedOnTable2 = this.DbContext.table2.Select(target => target.TargetID).Where(TargetID => TargetID == targetId).Count() > 0;
            isUsedOnTable3 = this.DbContext.table3.Select(target => target.TargetId).Where(targetID => targetID == targetId).Count() > 0;
            isUsedOnTable4 = this.DbContext.table4.Select(target => target.TargetID).Where(targetID => targetID == targetId).Count() > 0;

            return (isUsedOnTable1 || isUsedOnTable2 || isUsedOnTable3 || isUsedOnTable4);
        }

Этот подход технически работает, проблема здесь в проблемах производительности, связанных с наличием 4 разных запросов. каждый раз, когда эта функция выполняется. Есть ли способ проверить четыре таблицы одновременно или любой другой способ повысить производительность?

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 06 августа 2020

Мы предполагаем, что результат первого запроса вернет истину, вам не нужно запрашивать другие таблицы. Кроме того, вам не нужен подсчет данных. Так должно быть

  public async Task<bool> CheckIfUsed(int targetId)
        {
            var isUsed = false;
            isUsed = await this.DbContext.table1.AsNoTracking().AnyAsync(TargetID => TargetID == targetId);
            if (isUsed)
                return isUsed;
            
            isUsed = await this.DbContext.table2.AsNoTracking().AnyAsync(TargetID => TargetID == targetId);
            if (isUsed)
                return isUsed;
            
            isUsed = await this.DbContext.table3.AsNoTracking().AnyAsync(TargetID => TargetID == targetId);
            if (isUsed)
                return isUsed;
            
            isUsed = await this.DbContext.table4.AsNoTracking().AnyAsync(TargetID => TargetID == targetId);
            return isUsed;
        }
0 голосов
/ 06 августа 2020

Вы можете использовать .AsNoTracking() и async, чтобы отключить отслеживание сущностей и асинхронное выполнение, чтобы повысить производительность, как это

public async Task<bool> CheckIfUsed(int targetId)
{
    Task<int> isUsedOnTable1Task = false;
    Task<int> isUsedOnTable2Task = false;
    Task<int> isUsedOnTable3Task = false;
    Task<int> isUsedOnTable4Task = false;

    bool isUsedOnTable1 = false;
    bool isUsedOnTable2 = false;
    bool isUsedOnTable3 = false;
    bool isUsedOnTable4 = false;

    isUsedOnTable1Task = this.DbContext.table1.AsNoTracking().Select(target => target.TargetID).Where(TargetID => TargetID == targetId).CountAsync();
    isUsedOnTable2Task = this.DbContext.table2.AsNoTracking().Select(target => target.TargetID).Where(TargetID => TargetID == targetId).CountAsync();
    isUsedOnTable3Task = this.DbContext.table3.AsNoTracking().Select(target => target.TargetId).Where(targetID => targetID == targetId).CountAsync();
    isUsedOnTable4Task = this.DbContext.table4.AsNoTracking().Select(target => target.TargetID).Where(targetID => targetID == targetId).CountAsync();

    await Task.WhenAll(isUsedOnTable1Task, isUsedOnTable2Task, isUsedOnTable3Task, isUsedOnTable4Task)
    
    isUsedOnTable1 = isUsedOnTable1Task.Result > 0;
    isUsedOnTable2 = isUsedOnTable2Task.Result > 0;
    isUsedOnTable3 = isUsedOnTable3Task.Result > 0;
    isUsedOnTable4 = isUsedOnTable4Task.Result > 0;

    return (isUsedOnTable1 || isUsedOnTable2 || isUsedOnTable3 || isUsedOnTable4);
}

Помните, что EntityFramework не потокобезопасность

0 голосов
/ 06 августа 2020

я думаю, вы должны использовать сначала where, чтобы улучшить производительность

this.DbContext.table1.Where(TargetID => TargetID == targetId).Select(target => target.TargetID).Count()

Поскольку вы сначала извлекаете данные, а затем обрабатываете их

в противном случае

вы генерируете Generi c класс, который получает запрос объекта, затем получает команды из них и один огромный пакет надеюсь, это вам поможет

GoodLuck

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