Сообщение Re[71]: EntityFramework - тормоз от 12.05.2015 11:36
Изменено 12.05.2015 11:41 STDray
Здравствуйте, Evgeny.Panasyuk, Вы писали:
Большой тред, пропустил ветку.
EP>Что конкретно
Речь про 1 и 2.
>1) Запросы статические по сути, но сконструированные из нескольких частей, возможно даже в разных функциях.
>2) Статические запросы построенные через динамическую композицию — статические части запроса комбинируются разными способами в зависимости от runtime условий (то есть расширение пункта 1).
Да, именно этот вариант мне и не понятен.
Из того что я понял, предлагается представить AST-запроса в типе и производить вычисления в typelevel. Тогда вопрос не к макросам, а к системе типов. Ни в C#, ни в Nemerle typelevel вычислений не предвидится, потому я и хотел узнать у IT, как он видит linq в compile time, и как ему могла помочь Nitra.
EP>Вот здесь
>При попытке выполнить этот запрос, будет произведено 4 runtime проверки, в результате чего будет выбрана одна из 16 сгенерированных в compile-time версий запроса (причём которые могут кардинально отличаться друг от друга).
>Если не нравится экспоненциальное количество запросов в исполняемом файле, то можно добавить динамики. Да, при этом запрос будет частично строится в runtime (с возможным кэшированием), но при этом не будет дорогой runtime reflection — в ней тут нет принципиальной необходимости, достаточно compile-time reflection.
Для наглядности заменил условия
Тут, со слов IT, мы на каждый qN.Where(e.SomeFiels == someValue), где someValue может быть null, получаем еще по 2 варианта sql-запроса (с параметром и с 'is null'). Соответственно, число генерируемых запросов растет по экспоненте не только от количества условий, но и от числа нуллабельных переменных.
>4) Стирание полного типа запроса — это позволяет частично отличающимся запросам иметь одинаковый тип. Степень отличия контролируется тем, насколько стёрт тип.
>Насколько я вижу, вариант 4) тоже далеко не всегда необходим. Причём каких-то принципиальных предпосылок/аргументов к его необходимости в этом топике я не увидел.
Всегда или нет, но я видел множество ярлычков с какой-то часто используемой логикой вроде:
Итог:
1. нужен язык, поддерживающий вычисления в typelevel
2. размер генерируемого кода растет экспоненциально от числа условий и числа нуллабельных переменных (это только пример с Where разобрали)
3. при изменение запроса, весь зависимый код должен быть перекомпилирован
4. создание публичного интерфейса (типо паттерна "репозиторий") заруднено
5. непонятно, при чем здесь макросы
Большой тред, пропустил ветку.
EP>Что конкретно
Автор: Evgeny.Panasyuk
Дата: 19.04.15
имеется в виду?Дата: 19.04.15
Речь про 1 и 2.
>1) Запросы статические по сути, но сконструированные из нескольких частей, возможно даже в разных функциях.
>2) Статические запросы построенные через динамическую композицию — статические части запроса комбинируются разными способами в зависимости от runtime условий (то есть расширение пункта 1).
Да, именно этот вариант мне и не понятен.
Из того что я понял, предлагается представить AST-запроса в типе и производить вычисления в typelevel. Тогда вопрос не к макросам, а к системе типов. Ни в C#, ни в Nemerle typelevel вычислений не предвидится, потому я и хотел узнать у IT, как он видит linq в compile time, и как ему могла помочь Nitra.
EP>Вот здесь
Автор: Evgeny.Panasyuk
Дата: 14.04.15
вариант решения.Дата: 14.04.15
auto q1 = context.Employees;
auto q2 = conditional(!IsNullOrEmpty(lastName), q1.Where(e.LastName = lastName));
auto q3 = conditional(!IsNullOrEmpty(firstName), q2.Where(e.FirstName= firstName));
auto q4 = conditional(HasValue(employmentDateFrom), q3.Where(e.EmploymentDate >= employmentDateFrom.Value));
auto q5 = conditional(HasValue(employmentDateTo)), q4.Where(e.EmploymentDate <= employmentDateTo.Value));
//далее в Presentation Layer (в другом месте)
auto list = await q5.Take(pageSize).Select(/*projection*/).ToListAsync();
>При попытке выполнить этот запрос, будет произведено 4 runtime проверки, в результате чего будет выбрана одна из 16 сгенерированных в compile-time версий запроса (причём которые могут кардинально отличаться друг от друга).
>Если не нравится экспоненциальное количество запросов в исполняемом файле, то можно добавить динамики. Да, при этом запрос будет частично строится в runtime (с возможным кэшированием), но при этом не будет дорогой runtime reflection — в ней тут нет принципиальной необходимости, достаточно compile-time reflection.
Для наглядности заменил условия
auto q2 = conditional(searchParams.HasFilterByLastName, q1.Where(e.LastName == searchParams.LastName));
auto q3 = conditional(searchParams.HasFilterByFirstName, q2.Where(e.FirstName == searchParams.FirstName));
Тут, со слов IT, мы на каждый qN.Where(e.SomeFiels == someValue), где someValue может быть null, получаем еще по 2 варианта sql-запроса (с параметром и с 'is null'). Соответственно, число генерируемых запросов растет по экспоненте не только от количества условий, но и от числа нуллабельных переменных.
>4) Стирание полного типа запроса — это позволяет частично отличающимся запросам иметь одинаковый тип. Степень отличия контролируется тем, насколько стёрт тип.
>Насколько я вижу, вариант 4) тоже далеко не всегда необходим. Причём каких-то принципиальных предпосылок/аргументов к его необходимости в этом топике я не увидел.
Всегда или нет, но я видел множество ярлычков с какой-то часто используемой логикой вроде:
public IQuerable<Employe> ActiveEmployees { return _context.Employees.Where(e => e.IsActive); }
Итог:
1. нужен язык, поддерживающий вычисления в typelevel
2. размер генерируемого кода растет экспоненциально от числа условий и числа нуллабельных переменных (это только пример с Where разобрали)
3. при изменение запроса, весь зависимый код должен быть перекомпилирован
4. создание публичного интерфейса (типо паттерна "репозиторий") заруднено
5. непонятно, при чем здесь макросы
Re[71]: EntityFramework - тормоз
Здравствуйте, Evgeny.Panasyuk, Вы писали:
Большой тред, пропустил ветку.
EP>Что конкретно
Речь про 1 и 2.
>1) Запросы статические по сути, но сконструированные из нескольких частей, возможно даже в разных функциях.
>2) Статические запросы построенные через динамическую композицию — статические части запроса комбинируются разными способами в зависимости от runtime условий (то есть расширение пункта 1).
Да, именно этот вариант мне и не понятен.
Из того что я понял, предлагается представить AST-запроса в типе и производить вычисления в typelevel. Тогда вопрос не к макросам, а к системе типов. Ни в C#, ни в Nemerle typelevel вычислений не предвидится, потому я и хотел узнать у IT, как он видит linq в compile time, и как ему могла помочь Nitra.
EP>Вот здесь
>При попытке выполнить этот запрос, будет произведено 4 runtime проверки, в результате чего будет выбрана одна из 16 сгенерированных в compile-time версий запроса (причём которые могут кардинально отличаться друг от друга).
>Если не нравится экспоненциальное количество запросов в исполняемом файле, то можно добавить динамики. Да, при этом запрос будет частично строится в runtime (с возможным кэшированием), но при этом не будет дорогой runtime reflection — в ней тут нет принципиальной необходимости, достаточно compile-time reflection.
Для наглядности заменил условия
Тут, со слов IT, мы на каждый qN.Where(e.SomeField == someValue), где someValue может быть null, получаем еще по 2 варианта sql-запроса (с параметром и с 'is null'). Соответственно, число генерируемых запросов растет по экспоненте не только от количества условий, но и от числа нуллабельных переменных.
>4) Стирание полного типа запроса — это позволяет частично отличающимся запросам иметь одинаковый тип. Степень отличия контролируется тем, насколько стёрт тип.
>Насколько я вижу, вариант 4) тоже далеко не всегда необходим. Причём каких-то принципиальных предпосылок/аргументов к его необходимости в этом топике я не увидел.
Всегда или нет, но я видел множество ярлычков с какой-то часто используемой логикой вроде:
Итог:
1. нужен язык, поддерживающий вычисления в typelevel
2. размер генерируемого кода растет экспоненциально от числа условий и числа нуллабельных переменных (это только пример с Where разобрали)
3. при изменение запроса, весь зависимый код должен быть перекомпилирован
4. создание публичного интерфейса (типо паттерна "репозиторий") затруднено
5. непонятно, при чем здесь макросы
Большой тред, пропустил ветку.
EP>Что конкретно
Автор: Evgeny.Panasyuk
Дата: 19.04.15
имеется в виду?Дата: 19.04.15
Речь про 1 и 2.
>1) Запросы статические по сути, но сконструированные из нескольких частей, возможно даже в разных функциях.
>2) Статические запросы построенные через динамическую композицию — статические части запроса комбинируются разными способами в зависимости от runtime условий (то есть расширение пункта 1).
Да, именно этот вариант мне и не понятен.
Из того что я понял, предлагается представить AST-запроса в типе и производить вычисления в typelevel. Тогда вопрос не к макросам, а к системе типов. Ни в C#, ни в Nemerle typelevel вычислений не предвидится, потому я и хотел узнать у IT, как он видит linq в compile time, и как ему могла помочь Nitra.
EP>Вот здесь
Автор: Evgeny.Panasyuk
Дата: 14.04.15
вариант решения.Дата: 14.04.15
auto q1 = context.Employees;
auto q2 = conditional(!IsNullOrEmpty(lastName), q1.Where(e.LastName = lastName));
auto q3 = conditional(!IsNullOrEmpty(firstName), q2.Where(e.FirstName= firstName));
auto q4 = conditional(HasValue(employmentDateFrom), q3.Where(e.EmploymentDate >= employmentDateFrom.Value));
auto q5 = conditional(HasValue(employmentDateTo)), q4.Where(e.EmploymentDate <= employmentDateTo.Value));
//далее в Presentation Layer (в другом месте)
auto list = await q5.Take(pageSize).Select(/*projection*/).ToListAsync();
>При попытке выполнить этот запрос, будет произведено 4 runtime проверки, в результате чего будет выбрана одна из 16 сгенерированных в compile-time версий запроса (причём которые могут кардинально отличаться друг от друга).
>Если не нравится экспоненциальное количество запросов в исполняемом файле, то можно добавить динамики. Да, при этом запрос будет частично строится в runtime (с возможным кэшированием), но при этом не будет дорогой runtime reflection — в ней тут нет принципиальной необходимости, достаточно compile-time reflection.
Для наглядности заменил условия
auto q2 = conditional(searchParams.HasFilterByLastName, q1.Where(e.LastName == searchParams.LastName));
auto q3 = conditional(searchParams.HasFilterByFirstName, q2.Where(e.FirstName == searchParams.FirstName));
Тут, со слов IT, мы на каждый qN.Where(e.SomeField == someValue), где someValue может быть null, получаем еще по 2 варианта sql-запроса (с параметром и с 'is null'). Соответственно, число генерируемых запросов растет по экспоненте не только от количества условий, но и от числа нуллабельных переменных.
>4) Стирание полного типа запроса — это позволяет частично отличающимся запросам иметь одинаковый тип. Степень отличия контролируется тем, насколько стёрт тип.
>Насколько я вижу, вариант 4) тоже далеко не всегда необходим. Причём каких-то принципиальных предпосылок/аргументов к его необходимости в этом топике я не увидел.
Всегда или нет, но я видел множество ярлычков с какой-то часто используемой логикой вроде:
public IQuerable<Employe> ActiveEmployees { return _context.Employees.Where(e => e.IsActive); }
Итог:
1. нужен язык, поддерживающий вычисления в typelevel
2. размер генерируемого кода растет экспоненциально от числа условий и числа нуллабельных переменных (это только пример с Where разобрали)
3. при изменение запроса, весь зависимый код должен быть перекомпилирован
4. создание публичного интерфейса (типо паттерна "репозиторий") затруднено
5. непонятно, при чем здесь макросы