Время генерации первого sql-запроса кода EF

#asp.net-mvc #entity-framework #ef-code-first

#asp.net-mvc #entity-framework #ef-code-first

Вопрос:

В нашем решении мы сначала используем код. Во время разработки мы обнаружили проблему, заключающуюся в том, что генерация SQL-запросов занимает много времени (около 1-2 секунд).

В целом система выглядит следующим образом:
1. У нас есть общий репозиторий — все данные проходят через этот репозиторий:

 public virtual IEnumerable<T> Find<T>(Expression<Func<T, bool>> where, params Func<IQueryable<T>, IQueryable<T>>[] entitySet) where T : class
        {
            var q = this.Context.GetDbSet<T>();

            if (entitySet != null)
            {
                foreach (var func in entitySet)
                {
                    q = func(q);
                }
            }

            return q.AsExpandable().Where(where).ToList();
        }
 

Используя этот метод, мы получаем данные из базы данных (передавая нужные нам параметры).

SQL-запрос, сгенерированный EF, хорош (данные быстро извлекаются из базы данных, поэтому это не узкое место). Насколько мы понимаем, проблема заключается в генерации SQL-оператора.

У кого-нибудь есть ответ?

Важная информация:
Мы используем MySQL (Amazon RDS) с .NET Connector 6.4.4

Мы пытались использовать CompiledQuery , но это не работает с Code First (может быть, кто-нибудь знает обходной путь?).

——ОБНОВЛЕНО——

Есть пример запроса linq:

 var foundGreeting = GenericRepository.Instance.Find<Greetings>(
                                      greeting => currentTime >= greeting.From amp;amp; currentTime <= greeting.Due,
                                      entitySet => entitySet.Include(g => g.Labels),
                                      entitySet => entitySet.Include(g => g.Labels.Versions)).FirstOrDefault();
 

Это генерирует:

 SELECT
`Project1`.`GreetingId`, 
`Project1`.`From`, 
`Project1`.`Due`, 
`Project1`.`TextLabelId`, 
`Project1`.`LabelId`, 
`Project1`.`Key`, 
`Project1`.`Description`, 
`Project1`.`ModuleId`, 
`Project1`.`C1`, 
`Project1`.`VersionId`, 
`Project1`.`LabelId1`, 
`Project1`.`LanguageId`, 
`Project1`.`UserId`, 
`Project1`.`VersionTypeId`, 
`Project1`.`VersionNumber`, 
`Project1`.`Value`, 
`Project1`.`DepartmentId`, 
`Project1`.`IsExternal`, 
`Project1`.`EnableInheritance`
FROM (SELECT
`Extent1`.`GreetingId`, 
`Extent1`.`From`, 
`Extent1`.`Due`, 
`Extent1`.`TextLabelId`, 
`Extent2`.`LabelId`, 
`Extent2`.`Key`, 
`Extent2`.`Description`, 
`Extent2`.`ModuleId`, 
`Extent3`.`VersionId`, 
`Extent3`.`LabelId` AS `LabelId1`, 
`Extent3`.`LanguageId`, 
`Extent3`.`UserId`, 
`Extent3`.`VersionTypeId`, 
`Extent3`.`VersionNumber`, 
`Extent3`.`Value`, 
`Extent3`.`DepartmentId`, 
`Extent3`.`IsExternal`, 
`Extent3`.`EnableInheritance`, 
CASE WHEN (`Extent3`.`VersionId` IS  NULL) THEN (NULL)  ELSE (1) END AS `C1`
FROM `Greetings` AS `Extent1` INNER JOIN `Labels` AS `Extent2` ON `Extent1`.`TextLabelId` = `Extent2`.`LabelId` LEFT OUTER JOIN `Versions` AS `Extent3` ON `Extent3`.`LabelId` = `Extent1`.`TextLabelId`
 WHERE ('11:51:45' >= `Extent1`.`From`) AND ('11:51:45' <= `Extent1`.`Due`)) AS `Project1`
 ORDER BY 
`Project1`.`GreetingId` ASC, 
`Project1`.`LabelId` ASC, 
`Project1`.`C1` ASC
-- p__linq__0 (dbtype=Time, size=0, direction=Input) = 11:51:45
-- p__linq__1 (dbtype=Time, size=0, direction=Input) = 11:51:45
 

Комментарии:

1. Вся сложность генерации вашего запроса скрыта в ваших переданных делегатах, где условие и AsExpendable вызов. Покажите некоторый пример запроса, для генерации которого требуется много времени, но на данный момент похоже, что вы создаете универсальное решение supper, у которого просто есть один недостаток его общего характера — он медленный. В таком случае первым шагом должно быть переписывание запроса в статический и сравнение времени его генерации.

2. Привет! Спасибо за ваш ответ. Я обновил вопрос