Здравствуйте, alex_public, Вы писали:
>>Покажи аналог на С++
_>Ты снова описываешь решение, а не задачу. Давай задачку и там посмотрим как её оптимально решить. Пока что ты просил универсальный доступ к базам данных. Я тебе показал красивый и удобный универсальный вариант. Давай, покажи что теперь ещё хочешь...)))
Внятный OR/Mapper. Годится ? Только ты уже расслабься, EP уже всё показал.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Для compile-time обработки выражений есть Boost.Proto — он берёт большую часть работы на себя. EP>Но, деревья выражений можно строить и в runtime — там вообще нет ничего сложного
Ога. Ты лучше покажи либу, которая умеет столько же бд, как и всякие дотнетовские аналоги. Ну, возьмем опенсорс — linq2db
Здравствуйте, Ikemefula, Вы писали:
NB>>принципиальные ограничения мы выдумываем себе сами. NB>>сформировать запрос по автоматически сгенерированным типам -- задача вполне реальная.
I>А что, где ты было сказано что это нереальная задача ?
ну эт ты начал рассказывать про какие-то непонятные трудности
I>Покажи пример, хотя бы вот такой пример order.Select(x => x.Total)
order x;
auto r = db::select( x.Total ).eval( );
I>Такие вещи почти не встречаются. Обычно чтото сложнее, например так — order.Where(x => x.State == State.Closed).Select(x => x.Total)
order x;
auto r = db::select( x.Total ).where( x.State == State.Closed ).eval( );
I>А еще интереснее вот так — order.Where(Filter).Select(x => x.Total), где фильтр это почти обычная фукнция.
интереснее здесь то, где фильтруются полученные данные.
NB>>>>из конфига в смысле в рантайме.
I>>>Именно так.
NB>>в рантайме маппинг генерируешь? ну-ну.
I>Где он генерируется, не важно. Важно, что это делается не руками.
Здравствуйте, Ikemefula, Вы писали:
I>Ога. Ты лучше покажи либу, которая умеет столько же бд, как и всякие дотнетовские аналоги. Ну, возьмем опенсорс — linq2db
ODB поддерживает mainstream (хотя может это и не mainstream уже, я с DB не работаю — нет таких задач):
MySQL, SQLite, PostgreSQL, Oracle, MSSQL.
О, сорри, не заметил. Если говорим про библиотечку SOCI, то это она всё сама делает внутри. Собственно там две основных схемы для этого:
1. Возвращается итератор. Тут соответственно размер вообще не надо указывать, т.к. тут получается по запросу к базе на каждую строку. Это весьма удобно, но не всегда оптимально по быстродействию.
2. Выгружаем данные сразу в некий массив (вектор нужного типа) одним запросом. Тогда запрашивается как раз сколько надо автоматом.
Здравствуйте, Ikemefula, Вы писали:
I>Внятный OR/Mapper. Годится ? Только ты уже расслабься, EP уже всё показал.
Так пример этого же был в две строки буквально на заглавной странице той простенькой библиотечки, что я тебе показывал. Ну могу показать чуть подробнее:
struct Person{
int id;
string name;
double total;
};
for(auto& p: rowset<Person>(session(sqlite3, "test.db").prepare<<"select * from Persons"))
wcout<<p.id<<' '<<p.name<<' '<<p.total<<endl;
Ну а Евгений показал уже что-то совсем мощное, с автогенерацией кода и т.п...
Здравствуйте, QrystaL, Вы писали:
QL>Вот мы пишем
QL>
QL>using (var db = new DataContext())
QL>{
QL> var products = db
QL> .Products
QL> .Take(5)
QL> .ToArray();
QL>}
QL>
QL>Для этого кода безразлично, какая СУБД используется — Oracle, MySQL, MS SQL и т.д. QL>То есть при запуске, если в ConnectionString: QL>a) прописана база MS SQL, то сгенерируется соответствующий SQL вида SELECT TOP 5 * FROM Products QL>б) прописан MySQL, то сгенерируется SQL вида SELECT * FROM Products LIMIT 5 QL>в) ...
Ну на это я уже ответил — см. два мои сообщения выше в темке. )
QL>Таким образом, задача вообще не писать SQL руками, а простой сменой 1 строчки в конфиг файле перейти на другую СУБД.
Здравствуйте, night beast, Вы писали:
NB>ну эт ты начал рассказывать про какие-то непонятные трудности
Сложность реализации мягко говоря разная.
I>>А еще интереснее вот так — order.Where(Filter).Select(x => x.Total), где фильтр это почти обычная фукнция.
NB>интереснее здесь то, где фильтруются полученные данные.
Неужели в компайлтайм ?
I>>Где он генерируется, не важно. Важно, что это делается не руками.
NB>а кто заставляет генерировать руками в плюсах?
Здравствуйте, Evgeny.Panasyuk, Вы писали:
I>>Ога. Ты лучше покажи либу, которая умеет столько же бд, как и всякие дотнетовские аналоги. Ну, возьмем опенсорс — linq2db
EP>ODB поддерживает mainstream (хотя может это и не mainstream уже, я с DB не работаю — нет таких задач): EP>MySQL, SQLite, PostgreSQL, Oracle, MSSQL.
То есть, ни о чем Вот чудо — есть мега пулька, но шота люди ей не пользуются
Здравствуйте, alex_public, Вы писали:
_>Так пример этого же был в две строки буквально на заглавной странице той простенькой библиотечки, что я тебе показывал. Ну могу показать чуть подробнее: _>
Здравствуйте, Ikemefula, Вы писали:
I>>>А еще интереснее вот так — order.Where(Filter).Select(x => x.Total), где фильтр это почти обычная фукнция.
NB>>интереснее здесь то, где фильтруются полученные данные.
I>Неужели в компайлтайм ?
ключевое слово, "где". ну да не важно. ответ я услышал.
Здравствуйте, alex_public, Вы писали:
I>>Ты показал чтото непонятное — Persons так же должно быть типизированым, а у тебя это в строчке.
_>Ээээ что? ) Имя таблицы в базе данных типизированное? )))
Здравствуйте, Ikemefula, Вы писали:
I>А имя переменной типизировано или нет ?
I>Типа ты не понял, ага
Если ты про то, чтобы жёстко связать имя таблицы и класс, как было в примерах к ODB, то на мой взгляд это не удобная схема. Мы же можем использовать один и тот же класс с разными таблицами... Но если вдруг всё же захочется такого, то тоже без проблем делается. И даже без всякой внешней кодогенерации. С учётом того, что soci делает всю основную работу (поддерживает все виды баз данных с единым удобным интерфейсом и пользовательскими типами), то реализовать подобное можно уже в десяток строк. Например для класса
struct Person{
int id;
string name;
double total;
int runtime=time(nullptr);//не сохраняем в базу
};
Причём функции CreateTable, Insert, Select и т.п. ничего не знают о Person, т.е. они общие для всех. И больше никакого дополнительного кода, кроме показанного выше объявления, писать не требуется. Причём все будет происходить жёстко типизированно... )
Так что, как видишь, все эти маппинги и т.п. — это всё ерунда, реализуемая в несколько строк. А самое сложное, это написать кучу кода реализующего работу сразу со всеми библиотеками. Что и сделано например в библиотечка soci и многих других.
Здравствуйте, alex_public, Вы писали:
_>Так что, как видишь, все эти маппинги и т.п. — это всё ерунда, реализуемая в несколько строк. А самое сложное, это написать кучу кода реализующего работу сразу со всеми библиотеками. Что и сделано например в библиотечка soci и многих других.
soci это вообще никакой типизации, все строчками, неинтересно. odb уже интереснее, но шота при одинаковом размере кода с linq2db имеет вдвое меньше провайдеров. Да и по возможностям как то не впечатляет
Здравствуйте, Ikemefula, Вы писали:
I> Да и по возможностям как то не впечатляет
Есть ли в linq2db генерация схемы (вообще, есть ли какая-нибудь схема), автоматическая миграция между разными версиями схемы?
Есть ли нормальная поддержка типов/mapping'ов, а не только POCO? Наследование, абстрактные классы?
Здравствуйте, Ikemefula, Вы писали:
I>soci это вообще никакой типизации, все строчками, неинтересно.
Не, там запросы строчками, а данные все типизированы. А я тебе показал как тривиально ещё и запросы сделать типизированными. ))) Другой вопрос в том а надо ли оно...
I>odb уже интереснее, но шота при одинаковом размере кода с linq2db имеет вдвое меньше провайдеров. Да и по возможностям как то не впечатляет
Нуу расскажи как делается в .net маппинг в таблицу некого нашего класса. Который естественно там уже от кого-то библиотечного пронаследован и соответственно имеет набор полей, которые не надо сохранять в базу.
Здравствуйте, alex_public, Вы писали:
I>>soci это вообще никакой типизации, все строчками, неинтересно.
_>Не, там запросы строчками, а данные все типизированы. А я тебе показал как тривиально ещё и запросы сделать типизированными. ))) Другой вопрос в том а надо ли оно...
Нужно что бы запросы были типизироваными.
I>>odb уже интереснее, но шота при одинаковом размере кода с linq2db имеет вдвое меньше провайдеров. Да и по возможностям как то не впечатляет
_>Нуу расскажи как делается в .net маппинг в таблицу некого нашего класса. Который естественно там уже от кого-то библиотечного пронаследован и соответственно имеет набор полей, которые не надо сохранять в базу.
POCO и в большинстве этого достаточно. Если чтото больше надо, то обычно атрибутами.
Здравствуйте, Evgeny.Panasyuk, Вы писали:
I>> Да и по возможностям как то не впечатляет
EP>Есть ли в linq2db генерация схемы (вообще, есть ли какая-нибудь схема), автоматическая миграция между разными версиями схемы? EP>Есть ли нормальная поддержка типов/mapping'ов, а не только POCO? Наследование, абстрактные классы?
Тут есть целый форум, можешь там спросить автора этого фремворка.