Re[37]: EntityFramework - тормоз
От: Evgeny.Panasyuk Россия  
Дата: 22.04.15 15:53
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Ок, я понял. Обстоят чуть хуже, чем никак:

S>
S>    auto x = select(apples.appleId, oranges.orangeId); // WTF is x???
S>


Это же простой пример не претендующий на полноту. При желании можно получить например такой синтаксис:
class Suppliers;

TABLE
(
    Products,
    (string, ProductName)
    (USD,  UnitPrice)
    (Suppliers*, supplier)
);

TABLE
(
    Suppliers,
    (string, CompanyName)
    (string, Address)
    (many<Products>, products)
);

// ...
{
    auto q = select(Suppliers::CompanyName, Products::ProductName).where(Products::UnitPrice > 11.99_USD); // auto join
    for(const auto &x : q.execute())
        cout << x.CompanyName << " " << x.ProductName << endl;
}
Отредактировано 22.04.2015 16:01 Evgeny.Panasyuk . Предыдущая версия . Еще …
Отредактировано 22.04.2015 16:00 Evgeny.Panasyuk . Предыдущая версия .
Re[51]: EntityFramework - тормоз
От: alex_public  
Дата: 22.04.15 19:44
Оценка:
Здравствуйте, AndrewVK, Вы писали:

_>>Да, кстати, пользуюсь случаем могу сообщить, что подписку (уведомления по почте) на новые сообщение в разделе вы так и не починили — ко мне ничего не приходит.

AVK>Тут я ничем не могу помочь, от нас все уходит.

Да, кто-то мне так и отвечал на форуме пару лет назад (когда оно сломалось). Только вот не уходит на самом деле. Где-то у вас там есть баг, который не можете увидеть. Вот если бы мне и уведомления о новых сообщения в теме не приходили, то я бы ещё мог поверить, что какие-то проблемы с моей почтой или чем-то подобным. Но раз они приходят, а это нет, то значит что банально не отправляется. Кстати, когда-то давно работало всё. Но потом вы затеяли некую переделку сайта и уведомления о новых темах перестали работать.

AVK>Это намек на то, что тебе, наверное, не хотелось бы получать багрепорты типа твоего.


Я вроде как вполне подробно описал проблему. Разве что точный текст ошибки вылезающей по таймауту не привёл, но думаю вы его и так сами знаете. )))
Re[53]: EntityFramework - тормоз
От: alex_public  
Дата: 22.04.15 20:03
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

_>>Возможно) Кстати, а как это выглядит в коде?

НС>В этом топике пример уже был. Запрос просто оборачивается CompiledQuery и полученный результат многократно используется.

Я что-то не помню такого. Или ты имеешь в виду, что в теме были просто linq запросы, а их как-то легко превращают в CompiledQuery? Так вот именно этот последний момент и интересует, а не сами linq запросы.
Re[47]: EntityFramework - тормоз
От: alex_public  
Дата: 22.04.15 20:53
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Не вызовет. Ты этот вопрос, помнится, уже задавал.


В этой теме не задавал. Я помнится когда-то давно спрашивал Ikemefula на эту тему, но он так и не смог тогда ответить. ) Я потому и запомнил его на будущее. )))

НС>>>С того что лишние поля будут выбираться без надобности.

_>>Ты всерьёз считаешь, что если запросить одну строку из БД целиком, то это будет ощутимо медленнее, чем запросить эту же строку без пары столбцов? )

НС>Всерьез считаю. Про index includes, к примеру, слышал? Так вот, они работают только при ограничении проекции. Я уж не говорю о том, что в таблицах могут быть вполне объемные блобы.


Ну мы же говорим не об обобщённом решение, а о специфическом для каждого случая. Если у нас вдруг будет таблица пользователей с объёмными бинарными данными, то значит сделаем другое решение. В каждом случае можно подобрать оптимальное. Но мне чаще всего попадались случаи, когда удобнее всего забирать пользователя целиком (прямо при проверке id сессии).

НС>Ниче не понял. IQueryable, если что, он на самом деле IQueryable<T> в котором Т вполне себе родной.


Так, давай всё же вернёмся к конкретным примерам. Вот у нас есть слой абстракции вида (такой почти псевдокод):
void AddUser(string name)
{
    query("insert ...");
    query("insert ...");
}
User GetUser(int id)
{
    return query("select ...");
}

Я думаю вполне понятно, как такой API будет использоваться из прикладного кода. А теперь можешь показать мне как будет выглядеть в прикладном коде данная функциональность без отдельного слоя абстракции (с помощью того же linq)?

_>>Как минимум надо понимать всякие там join'ы, подзапросы и т.п.

НС>Это надо в любом случае понимать, если ты хочешь получить эффективное решение.

Конечно, но в случая слоя абстракции достаточно чтобы это понимал только один специалист, а не все, работающие над приложением.

_>>Только в рамках реляционных СУБД.

НС>Не обязательно. Но я вот опять вижу витание в облаках. Тут тебе объясняют что даже смена одной РСУБД на другую — редчайшее явление, а уж замена РСУБД на нереляционное хранилище — это что то из области струнных теорий.

Ну вот если кто-то говорит, что "поддержка нескольких РСУБД — это редчайшее явление", то это просто автоматический диагноз, что человек вообще не в курсе веб-разработки. Если же говорить про одновременную поддержку sql и nosql БД, то это действительно пока что редкость. Но только потому, что собственно nosql БД начали обретать популярность не так давно. И уже некоторые такие движки (поддерживающие не только sql БД) я уже видел.
Re[46]: EntityFramework - тормоз
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 22.04.15 21:11
Оценка: +1
Здравствуйте, alex_public, Вы писали:

_>Здравствуйте, Ночной Смотрящий, Вы писали:


_>>>В произвольном случае конечно. Однако для конкретной задачи (особенно если в ней нет произвольных деревьев) это становится более реально.

НС>>Ну а для конкретного случая и у линка проблем нет.

_>Кстати, давно хотел спросить. А если нам понадобится обеспечивать сохранения в БД состояния (естественно не со всеми полями — всякие там дескрипторы и т.п. не нужны) некого уже существующего (скажем наследника тяжёлого библиотечного класса) сложного класса, то это вызовет какие-то сложности или же тоже без проблем?

Маппинг можно практически любой сделать.

_>>>С чего бы это? )

НС>>С того что лишние поля будут выбираться без надобности.
_>Ты всерьёз считаешь, что если запросить одну строку из БД целиком, то это будет ощутимо медленнее, чем запросить эту же строку без пары столбцов? )
Это зависит от того как получать. Если по ключу, то разницы почти не будет. А если с предикатом по неключевому полю, то с покрывающим индексом по части полей будет в 3-4 раза быстрее чем тянуть полные строки, и гораздо меньше чтений понадобится. Да еще и вероятность дедлоков на read commited появится.

Я же говорил, бросай показывать незнание БД.

_>>> Без уточнения конкретной задачи это всё бессмысленный разговор.

НС>>Тут все вполне конкретно. В реальных задачах набор полей в основном уникален. Рисовать на каждый случай новый тип — геморой, возвращать недозаполненный тип или безликий кортеж — отличный способ прострелить себе ногу, возвращать все поля — удар по перформансу.

_>В реальных задачах чаще всего надо или всю строку или одно поле из неё. )

Да конечно. Чаще всего для список требуется подмножество полей, причем небольшое относительно всего размера строки.

_>И даже если в каком-то редком случае понадобится именно некий набор полей, то это тоже без проблем и удобно задаётся в API для случая статических запросов.

Ну хватит уже показывать свое незнание. Вот представь что ты наплодил 10 методов, которые возвращают разные проекции пользователя, а тут внезапно у нас добавляется поле в базу, по которому надо фильтровать и ты идешь и 10 методов правишь, которые только проекцией и отличаются. Это просто кладезь багов. Ты никогда такого не писал и совершенно не представляешь о чем пишешь.


_>>>- родное (через свои типы) API к хранилищу

НС>>Что такое "родное API" и чем оно лучше неродного?
_>Я же указал в скобках — работает через те же типы данных, что и само приложение. И лучше оно удобством.
А в чем принципиальная проблема построить приложение, которое работает с теми же типами, с которыми работает БД? Зачем еще один слой косвенности и перекладывание туда-сюда? В идеале надо иметь классы данных для сущностей базы и отображения. Мапинг можно автоматически делать если naming conventions использовать.

_>>>- программистам в остальной части приложения не надо знать тонкости работы хранилища — этим может заниматься один спец. по нему

НС>>IQueryable обеспечивает тоже самое.
_>Как минимум надо понимать всякие там join'ы, подзапросы и т.п. Не говоря уже о том, что для некоторых БД некоторые типы запросов могут оказываться неэффективными.
Их в любом случае надо знать, а запрос скорее всего будет эффективен. Покачто известен ровно один случай когда это не так. Все остальное — следствие криворукости программиста.

_>>>- при необходимости можно легко сменить тип хранилища.

НС>>IQueryable обеспечивает тоже самое.
_>Только в рамках реляционных СУБД. Или быть может linq2db может помочь сохранить данные в MongoDB? )
Смена рсубд на не-реляционную базу принесет гораздо больше проблем, чем генерация запросов. У меня даже есть пример, когда пришлось сильно переделывать архитектуру из-а перехода на Mongodb (от чего в последствии отказались). И там кстати был такой слой как ты описываешь. Из-за вынужденной денормализации для хоть какого-то быстродействия в паре сценариев понадобилось batch-job-executor свой писать, который нещадно глючил. Так что мэпинг IQueryable на язык запросов конкретной субд — наименьшая их таких проблем.
Re[50]: EntityFramework - тормоз
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 22.04.15 21:14
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, Ночной Смотрящий, Вы писали:


EP>>>Вот кстати, а как быть с join'ом в случае связи один ко многим? Если делать один простой запрос, то в результате будет дублирование данных — например те самые объёмные блобы. Какова практика? Или что например делает linq2db?

НС>>Простой вопрос — без линка ты как сделаешь?

EP>У меня вопрос скорее не про LINQ, а про практику SQL (а потом уже как на неё отображается LINQ).

А что за запрос такой? Обычно на стороне связи где "много" стоит справочник, а откуда там блобы или зачем из тянуть в списке "дочерних" сущностей?
Re[38]: EntityFramework - тормоз
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 22.04.15 21:21
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, Sinclair, Вы писали:


S>>Ок, я понял. Обстоят чуть хуже, чем никак:

S>>
S>>    auto x = select(apples.appleId, oranges.orangeId); // WTF is x???
S>>


EP>Это же простой пример не претендующий на полноту. При желании можно получить например такой синтаксис:

EP>
EP>    auto q = select(Suppliers::CompanyName, Products::ProductName).where(Products::UnitPrice > 11.99_USD); // auto join
EP>


1) А если связи между таблицами нет?
2) А если связи две?
3) Если все таки сделаем ошибку что нам укажет компилятор?
4) Что будет если у нас в трех таблицах будет поле ID?
Re[52]: EntityFramework - тормоз
От: Evgeny.Panasyuk Россия  
Дата: 22.04.15 21:23
Оценка:
Здравствуйте, alex_public, Вы писали:

_>>>Да, кстати, пользуюсь случаем могу сообщить, что подписку (уведомления по почте) на новые сообщение в разделе вы так и не починили — ко мне ничего не приходит.

AVK>>Тут я ничем не могу помочь, от нас все уходит.
_>Да, кто-то мне так и отвечал на форуме пару лет назад (когда оно сломалось). Только вот не уходит на самом деле. Где-то у вас там есть баг, который не можете увидеть. Вот если бы мне и уведомления о новых сообщения в теме не приходили, то я бы ещё мог поверить, что какие-то проблемы с моей почтой или чем-то подобным. Но раз они приходят, а это нет, то значит что банально не отправляется. Кстати, когда-то давно работало всё. Но потом вы затеяли некую переделку сайта и уведомления о новых темах перестали работать.

У меня аналогичная ситуация — подписка на сообщения конкретной темы работает. А вот подписка на разделы — та которая в личных настройках "Получать первые сообщения тем для следующих форумов" — нет.
Re[51]: EntityFramework - тормоз
От: Evgeny.Panasyuk Россия  
Дата: 22.04.15 21:41
Оценка:
Здравствуйте, gandjustas, Вы писали:

EP>>>>Вот кстати, а как быть с join'ом в случае связи один ко многим? Если делать один простой запрос, то в результате будет дублирование данных — например те самые объёмные блобы. Какова практика? Или что например делает linq2db?

НС>>>Простой вопрос — без линка ты как сделаешь?
EP>>У меня вопрос скорее не про LINQ, а про практику SQL (а потом уже как на неё отображается LINQ).
G>А что за запрос такой? Обычно на стороне связи где "много" стоит справочник, а откуда там блобы или зачем из тянуть в списке "дочерних" сущностей?

Если блобы на стороне "много" — то при join'е они не дублируется. Дублируются значения со стороны "один".
Например нужно получить набор текстов форумных сообщений и список ключей пользователей поставивших like для каждого сообщения.
Re[52]: EntityFramework - тормоз
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 22.04.15 21:48
Оценка: 1 (1)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, gandjustas, Вы писали:


EP>>>>>Вот кстати, а как быть с join'ом в случае связи один ко многим? Если делать один простой запрос, то в результате будет дублирование данных — например те самые объёмные блобы. Какова практика? Или что например делает linq2db?

НС>>>>Простой вопрос — без линка ты как сделаешь?
EP>>>У меня вопрос скорее не про LINQ, а про практику SQL (а потом уже как на неё отображается LINQ).
G>>А что за запрос такой? Обычно на стороне связи где "много" стоит справочник, а откуда там блобы или зачем из тянуть в списке "дочерних" сущностей?

EP>Если блобы на стороне "много" — то при join'е они не дублируется. Дублируются значения со стороны "один".

Это я опечатался.

EP>Например нужно получить набор текстов форумных сообщений и список ключей пользователей поставивших like для каждого сообщения.

обычно два разных запроса идут, один получает сообщения и подсчет лайков, а второй затягивает список кто залайкал. Причем второй запрос зачастую отправляется с клиента уже (как на этом форуме).
Re[39]: EntityFramework - тормоз
От: Evgeny.Panasyuk Россия  
Дата: 22.04.15 22:13
Оценка:
Здравствуйте, gandjustas, Вы писали:

EP>>
EP>>    auto q = select(Suppliers::CompanyName, Products::ProductName).where(Products::UnitPrice > 11.99_USD); // auto join
EP>>


G>1) А если связи между таблицами нет?


Компилятор выдаст ошибку, а пользователь будет должен составить явный join.

G>2) А если связи две?


Возможны разные варианты реакции:
1) Ошибка компиляции так как неоднозначность. Пользователь должен выбрать связь или сделать явный join.
2) Некие правила для предпочтения связей.

Вообще, даже древний MS Access умел автоматически строить CRUD запросы по заданному списку полей из разных таблиц (как в примере выше).

G>3) Если все таки сделаем ошибку что нам укажет компилятор?


Какую именно?
Во время компиляции доступны данные об: таблицах, их полях/ключах, связях между ними, дерево запроса.
Всё это можно обрабатывать (во время компиляции) языком полным по Тьюрингу, делать какие угодно трансформации, обходить граф связей, дерево запроса, генерировать SQL, и останавливать компиляцию с ошибкой по любому возможному условию.

Например можно выполнять поиск пути между двумя таблицами по графу связей — и если такого пути нет или он не единственен (или какая там логика обычно применяется) — то выдавать ошибку компиляции при попытке вызывать такой auto join.

G>4) Что будет если у нас в трех таблицах будет поле ID?


Вопрос про что?
Если про alias — то это элементарно реализуется через дополнительный синтаксис as, пример есть в sqlpp11.
Если же про natural join по одинаковым колонкам, то я этого не предлагал (хотя это также возможно реализовать) — я подразумевал что пример выше использует информацию о связях.
Re[53]: EntityFramework - тормоз
От: Evgeny.Panasyuk Россия  
Дата: 22.04.15 22:24
Оценка:
Здравствуйте, gandjustas, Вы писали:

EP>>Например нужно получить набор текстов форумных сообщений и список ключей пользователей поставивших like для каждого сообщения.

G>обычно два разных запроса идут, один получает сообщения и подсчет лайков, а второй затягивает список кто залайкал.

В идеале конечно хотелось бы: один запрос, результат без дубликатов, быстро/эффективно, удобно и просто (без всяких конкатенаций).
Либо хотя бы отправить два запроса одновременно, да так чтобы работа базы для запроса со стороны "один" не дублировалась.

G>Причем второй запрос зачастую отправляется с клиента уже (как на этом форуме).


На этом форуме другая ситуация — список оценок не выводится вместе с текстом сообщения, только количество.
Re[47]: EntityFramework - тормоз
От: alex_public  
Дата: 23.04.15 06:31
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Это зависит от того как получать. Если по ключу, то разницы почти не будет. А если с предикатом по неключевому полю, то с покрывающим индексом по части полей будет в 3-4 раза быстрее чем тянуть полные строки, и гораздо меньше чтений понадобится. Да еще и вероятность дедлоков на read commited появится.

G>Я же говорил, бросай показывать незнание БД.

Вообще то в данном случае речь шла о вполне конкретной функции вида User GetUser(int id), так что твой комментарий совершенно не к месту. Хотя сам по себе он технически верный. )

_>>И даже если в каком-то редком случае понадобится именно некий набор полей, то это тоже без проблем и удобно задаётся в API для случая статических запросов.

G>Ну хватит уже показывать свое незнание. Вот представь что ты наплодил 10 методов, которые возвращают разные проекции пользователя, а тут внезапно у нас добавляется поле в базу, по которому надо фильтровать и ты идешь и 10 методов правишь, которые только проекцией и отличаются. Это просто кладезь багов. Ты никогда такого не писал и совершенно не представляешь о чем пишешь.

Очаровательно. ) Я пишу что "в редком случае", а он сразу же наплодил 10 таких редких случаев под одну таблицу. ))) Да, действительно я такого никогда не писал. ))) У меня собственно вообще запрос нескольких отдельных полей всегда был редкостью — почти всегда или вся строка или одно поле.

G>А в чем принципиальная проблема построить приложение, которое работает с теми же типами, с которыми работает БД? Зачем еще один слой косвенности и перекладывание туда-сюда? В идеале надо иметь классы данных для сущностей базы и отображения. Мапинг можно автоматически делать если naming conventions использовать.


Т.е. это приложение должно подстраиваться под хранилище, а не наоборот? ) Забавно... )))
А что касается перекладываний, то никто их не предлагает — можно сразу загружать из sql в нужные классы.

G>Их в любом случае надо знать, а запрос скорее всего будет эффективен. Покачто известен ровно один случай когда это не так. Все остальное — следствие криворукости программиста.


Не надо им знать sql вообще, если есть нормальный слой абстракции. Ну или мощная ORM в крайнем случае.

G>Смена рсубд на не-реляционную базу принесет гораздо больше проблем, чем генерация запросов. У меня даже есть пример, когда пришлось сильно переделывать архитектуру из-а перехода на Mongodb (от чего в последствии отказались). И там кстати был такой слой как ты описываешь. Из-за вынужденной денормализации для хоть какого-то быстродействия в паре сценариев понадобилось batch-job-executor свой писать, который нещадно глючил. Так что мэпинг IQueryable на язык запросов конкретной субд — наименьшая их таких проблем.


А никто и не говорил, что это легко. Однако если бы изначально был расклад "sql запросы, раскиданные по всему приложению", то переход был бы ещё намного печальнее.
Re[53]: EntityFramework - тормоз
От: alex_public  
Дата: 23.04.15 06:33
Оценка: 1 (1)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>У меня аналогичная ситуация — подписка на сообщения конкретной темы работает. А вот подписка на разделы — та которая в личных настройках "Получать первые сообщения тем для следующих форумов" — нет.


Забавное совпадение. Сейчас нас точно запишут за одного человека. )))

Кстати, там подписка новые темы есть не только в настройках. Есть ещё кнопочка подписки в самом разделе форума. Но и она не помогает исправить баг.
Re[48]: EntityFramework - тормоз
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 23.04.15 08:06
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Здравствуйте, gandjustas, Вы писали:


G>>Это зависит от того как получать. Если по ключу, то разницы почти не будет. А если с предикатом по неключевому полю, то с покрывающим индексом по части полей будет в 3-4 раза быстрее чем тянуть полные строки, и гораздо меньше чтений понадобится. Да еще и вероятность дедлоков на read commited появится.

G>>Я же говорил, бросай показывать незнание БД.

_>Вообще то в данном случае речь шла о вполне конкретной функции вида User GetUser(int id), так что твой комментарий совершенно не к месту. Хотя сам по себе он технически верный. )


И что? От того что ты сузил область обсуждения проблемы не исчезли. Это демагогический прием — "давайте рассмотрим маленький частный случай в котором выполняется условие Х, а потом неявно будем считать, что условие Х выполняется везде". К несчастью для тебя такой переход еще нужно обосновать. То что ты получая пользователя по id можешь вытягивать все поля примерно с той же скоростью, что и часть полей не говорит о том, что можно не писать проекции во всех остальных случаях.

_>>>И даже если в каком-то редком случае понадобится именно некий набор полей, то это тоже без проблем и удобно задаётся в API для случая статических запросов.

G>>Ну хватит уже показывать свое незнание. Вот представь что ты наплодил 10 методов, которые возвращают разные проекции пользователя, а тут внезапно у нас добавляется поле в базу, по которому надо фильтровать и ты идешь и 10 методов правишь, которые только проекцией и отличаются. Это просто кладезь багов. Ты никогда такого не писал и совершенно не представляешь о чем пишешь.

_>Очаровательно. ) Я пишу что "в редком случае", а он сразу же наплодил 10 таких редких случаев под одну таблицу. ))) Да, действительно я такого никогда не писал. ))) У меня собственно вообще запрос нескольких отдельных полей всегда был редкостью — почти всегда или вся строка или одно поле.

То что ты считаешь "редким случаем" на практике нужно чуть менее чем всегда. Любая выборка не по ключу — огромные тормоза при неиспользовании проекций. Поэтому при твоем подходе 10 функций выборки на каждую таблицу это еще очень по-божески.

G>>А в чем принципиальная проблема построить приложение, которое работает с теми же типами, с которыми работает БД? Зачем еще один слой косвенности и перекладывание туда-сюда? В идеале надо иметь классы данных для сущностей базы и отображения. Мапинг можно автоматически делать если naming conventions использовать.


_>Т.е. это приложение должно подстраиваться под хранилище, а не наоборот? ) Забавно... )))

В 99% случаев модель данных и приложение делает одна команда, поэтом неясно почему вообще кто-то должен подстраиваться.

_>А что касается перекладываний, то никто их не предлагает — можно сразу загружать из sql в нужные классы.

То есть таки надо делать проекции. И мы прекрасно понимаем что в реальности на каждую таблицу будет более одной проекции. Внимание вопрос, как это поддерживать? Что будет если в таблице появляются новые поля, новые предикаты итп? Каждый раз править десятки функций?

G>>Их в любом случае надо знать, а запрос скорее всего будет эффективен. Покачто известен ровно один случай когда это не так. Все остальное — следствие криворукости программиста.

_>Не надо им знать sql вообще, если есть нормальный слой абстракции. Ну или мощная ORM в крайнем случае.
Практика показывает что надо. Без понимания SQL и механизмов работы СУБД программисты делают хреновые запросы, никакие инструменты не помогают.

G>>Смена рсубд на не-реляционную базу принесет гораздо больше проблем, чем генерация запросов. У меня даже есть пример, когда пришлось сильно переделывать архитектуру из-а перехода на Mongodb (от чего в последствии отказались). И там кстати был такой слой как ты описываешь. Из-за вынужденной денормализации для хоть какого-то быстродействия в паре сценариев понадобилось batch-job-executor свой писать, который нещадно глючил. Так что мэпинг IQueryable на язык запросов конкретной субд — наименьшая их таких проблем.


_>А никто и не говорил, что это легко. Однако если бы изначально был расклад "sql запросы, раскиданные по всему приложению", то переход был бы ещё намного печальнее.

Нет, правка запросов — мелочь по сравнению с другими проблемами.
Re[54]: EntityFramework - тормоз
От: Ночной Смотрящий Россия  
Дата: 23.04.15 10:35
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Я что-то не помню такого.


Плохо. Но в гугле то тебя не забанили? Первая же ссылка ведет на MSDN — https://msdn.microsoft.com/en-us/library/vstudio/bb896297(v=vs.100).aspx
Re[48]: EntityFramework - тормоз
От: Ночной Смотрящий Россия  
Дата: 23.04.15 11:08
Оценка:
Здравствуйте, alex_public, Вы писали:

НС>>Всерьез считаю. Про index includes, к примеру, слышал? Так вот, они работают только при ограничении проекции. Я уж не говорю о том, что в таблицах могут быть вполне объемные блобы.

_>Ну мы же говорим не об обобщённом решение, а о специфическом для каждого случая.

И?

_> Если у нас вдруг будет таблица пользователей с объёмными бинарными данными, то значит сделаем другое решение.


Какое?

_> В каждом случае можно подобрать оптимальное.


Какое?

_> Но мне чаще всего попадались случаи, когда удобнее всего забирать пользователя целиком (прямо при проверке id сессии).


Ну вот прям на этом сайте — идем в профиль и видим один набор полей пользователя. Щелкаем по закладкам — получаем другие поля. Смотрим сообщения — там третьи поля. Список сообщений или оценок — там опять отдельный набор.

_>Я думаю вполне понятно, как такой API будет использоваться из прикладного кода.


С Add все понятно. Там и в линке IQueryable скорее всего не будет. Что насчет Select то?

_>>>Как минимум надо понимать всякие там join'ы, подзапросы и т.п.

НС>>Это надо в любом случае понимать, если ты хочешь получить эффективное решение.
_>Конечно, но в случая слоя абстракции достаточно чтобы это понимал только один специалист, а не все, работающие над приложением.

Нет, недостаточно. Потому что на практике прежде всего presentation layer определяет вид запроса, причем на каждой форме/страничке камк правило запросы уникальны. Так что же получается? Выборку практически всех данных делает твой специалист, html рисуют верстальщики, скрипты пишут тоже специальные люди. Так кому твое API тогда предназначено? Ненужной обезъянке, втыкающей в контроллер проброс вызова в твое возжеланное API?

НС>>Не обязательно. Но я вот опять вижу витание в облаках. Тут тебе объясняют что даже смена одной РСУБД на другую — редчайшее явление, а уж замена РСУБД на нереляционное хранилище — это что то из области струнных теорий.

_>Ну вот если кто-то говорит, что "поддержка нескольких РСУБД — это редчайшее явление", то это просто автоматический диагноз, что человек вообще не в курсе веб-разработки.

Ну ну. Много дон веб-разработал то? А то чета гложут меня смутные сомнения.
Отредактировано 24.04.2015 9:25 Ночной Смотрящий . Предыдущая версия .
Re[48]: EntityFramework - тормоз
От: Sinclair Россия https://github.com/evilguest/
Дата: 24.04.15 08:36
Оценка: +2
Здравствуйте, alex_public, Вы писали:
_>Очаровательно. ) Я пишу что "в редком случае", а он сразу же наплодил 10 таких редких случаев под одну таблицу. ))) Да, действительно я такого никогда не писал. ))) У меня собственно вообще запрос нескольких отдельных полей всегда был редкостью — почти всегда или вся строка или одно поле.
Это оттого, что вы путаете причину со следствием. Фанаты вашего подхода просто оставляют UI-разработчика наедине с единственной функцией GetUser(int userId). У него тупо нет другого выбора, кроме как есть тот API, который ему дали. Потом начинаются костыли типа "загрузка пользователя у нас дорогая, поэтому пусть делается один раз в сессию", и проблемы типа "если пользователь сменил ник в другой сессии, то ему надо перелониться в этой" и т.п.
В реальности набор полей практически уникален для каждого сценария использования, а сценариев в хорошем приложении в разы больше, чем сущностей информационной архитектуры.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[38]: EntityFramework - тормоз
От: Sinclair Россия https://github.com/evilguest/
Дата: 24.04.15 11:14
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, Sinclair, Вы писали:


S>>Ок, я понял. Обстоят чуть хуже, чем никак:

S>>
S>>    auto x = select(apples.appleId, oranges.orangeId); // WTF is x???
S>>


EP>Это же простой пример не претендующий на полноту. При желании можно получить например такой синтаксис:

1. простой вопрос: так что же всё-таки есть в этом sqlpp, кроме добрых намерений? А то вот некоторые по соседству смело утверждают, что есть прямо таки всё и из коробки. А вы пишете про "при желании"... Я, не имея С++ компилятора под рукой, склоняюсь к тому, что sqlpp11 умеет проверять только простейшие сценарии.

2. более сложный вопрос: а за счёт чего и как мы планируем порождать типы и контролировать корректность статически?
Попробуйте написать простейший запрос типа "покажи мне всех менеджеров, которые продали больше среднего в своих отделах в прошлом году". На sql это пишется тривиально:
WITH 
  SalesYearlyTotals (SalesPersonID, TotalSales, SalesYear)
AS
(
    SELECT SalesPersonID, SUM(TotalDue) AS TotalSales, YEAR(OrderDate) AS SalesYear
    FROM Sales.SalesOrderHeader
    WHERE SalesPersonID IS NOT NULL
       GROUP BY SalesPersonID, YEAR(OrderDate)
),
  SalesYearlyAverages
AS
(
    SELECT SalesBranchID, AVG(TotalSales) AS AverageSales, SalesYear
    FROM SalesYearlyTotals inner join SalesPersons on SalesYearlyTotals.SalesPersonId = SalesPersons.Id
    GROUP BY SalesBranchID, SalesYear
)
SELECT SalesPersonId 
  FROM SalesYearlyTotals 
  INNER JOIN SalesPersons on SalesYearlyTotals.SalesPersonID = SalesPersons.SalesPersonID
  INNER JOIN SalesYearlyAverages on SalesPersons.SalesBranchID = SalesYearlyAverages.SalesBranchID AND SalesYearlyTotals.SalesYear = SalesYearlyAverages.SalesYear
  where SalesYearlyTotals.TotalSales >= SalesYearlyAverages.AverageSales

Linq позволит мне разнести этапы определения CTE и сборки запроса, отчего код сильно выиграет в читаемости и редактируемости. При этом шаг вправо-влево будет отслеживаться компилятором, т.к. в процессе сборки дерева выводятся типы промежуточных результатов и всё проверяется. На первый взгляд, sqlpp не предлагает ничего интереснее констант для имён таблиц и полей.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[49]: EntityFramework - тормоз
От: alex_public  
Дата: 24.04.15 14:29
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>И что? От того что ты сузил область обсуждения проблемы не исчезли. Это демагогический прием — "давайте рассмотрим маленький частный случай в котором выполняется условие Х, а потом неявно будем считать, что условие Х выполняется везде". К несчастью для тебя такой переход еще нужно обосновать. То что ты получая пользователя по id можешь вытягивать все поля примерно с той же скоростью, что и часть полей не говорит о том, что можно не писать проекции во всех остальных случаях.


1. Я не сузил — именно в такой постановке вопрос был изначально.
2. Я как раз везде и говорю, что только делая разный код в каждой задаче (а не обобщённую ORM), можно добиться максимальной эффективности. Т.е. я как раз не предлагаю делать везде по образцу этого примера, а предлагаю искать оптимальное решение в каждом частном случае — это совсем не сложно.

_>>Т.е. это приложение должно подстраиваться под хранилище, а не наоборот? ) Забавно... )))

G>В 99% случаев модель данных и приложение делает одна команда, поэтом неясно почему вообще кто-то должен подстраиваться.

Причём тут команда? ) В случае использования в приложение классов, являющихся отображением slq таблиц, у тебя модель данных ограничена реляционной моделью. )

G>То есть таки надо делать проекции. И мы прекрасно понимаем что в реальности на каждую таблицу будет более одной проекции. Внимание вопрос, как это поддерживать? Что будет если в таблице появляются новые поля, новые предикаты итп? Каждый раз править десятки функций?


Как раз при такой архитектуре и удобнее поддерживать в случае изменения БД, потому как все правки будут локальные (весьма возможно вообще в одном файле), а не раскиданы по всему коду приложения.

_>>Не надо им знать sql вообще, если есть нормальный слой абстракции. Ну или мощная ORM в крайнем случае.

G>Практика показывает что надо. Без понимания SQL и механизмов работы СУБД программисты делают хреновые запросы, никакие инструменты не помогают.

Какие запросы? ) Все запросы сидят в слое абстракции, а наружу только функции без всяких опций. Так что при описанной архитектуре как раз можно иметь в команде только одного специалиста по БД. Более того, есть гарантии, что какой-нибудь криворукий новичок не накосячит со своими оригинальным запросом. )))
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.