В нашем решении мы используем 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 && 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