Э да!
V> Когда приводят примеры именно крутости Linq в том плане, что он позволил построить сложный запрос, в котором на SQL сам чёрт ногу сломит, то приводят именно встроенный синтаксис
Это личные примеры того кто приводит. Я здесь приводил примеры без этого. И вообще, кто и что приводит к обсуждению отношения не имеет.
V>А в приведенном тобой виде, повторюсь, мы могли это еще в 2004-м. ))
Подобные утверждения выдают твое полное непонимание того, что такое LINQ. Без expression tree LINQ невозможен в принципе.
НС>>Похожесть тебе только показалась. Ключевой момент здесь — наличие expression tree, которого в 2004 не было. А QC это так, мелочевка. V>Это у вас не было.
Это в C# не было.
V> А у нас — практически все используемые по-факту операции в выражениях T-SQL. И переопределение операторов, ес-но, для вменяемого синтаксиса.
Ты не понимаешь что такое expression tree.
НС>>За счет того что выкидывается куча странного кода внутри хранимок. Особо весело выходит, когда одна хранимка вызывает другую, та третью и т.д. V>Так это специально так делается.
О да, и специально от этого тормозит как не в себя. Потому что вызов хранимки в интерпретаторе SQL это дорого, и потому что средства декомпозии у SQL до жути убоги (из нормального в mssql, по сути, только inline functions).
НС>>Во-во, навертят бреда вокруг промежуточных таблиц на ровном месте с десятком select into, а потом оказывается что все можно переписать без них. V>До снятия ограничений с табличных ф-ий на рекурсию и до введения рекурсивных возможностей в SQL — нифига не всё.
Описываемые мной проблемы присутствовали без какой либо рекурсии.
V>Опять же. В любом случае, в процессе таких же точно вычислений точно так же создаются промежуточные результаты во временных таблицах, просто неявно.
Вот только перформанс с их выкидыванием, напоминаю, улучшался в разы.
V>А код с промежуточными результатами зачастую намного проще и, опять же, замечательно поддаётся декомпозиции и повторному использованию.
Код LINQ запросов неизмеримо лучше поддается декомпозиции, чем императивный код на T-SQL.
V>А какой смысл многократно расписывать одни и те же комбинации джоинов?
А не надо, внезапно, в LINQ расписывать руками джойны, представляешь?
Здравствуйте, Ночной Смотрящий, Вы писали:
V>>"Тупой" подразумевал без оптимизации НС>В BLT определенные оптимизации делаются.
В рамках логических/арифметических выражений?
V>>, то бишь без "понимания" самого запроса НС>Что такое "понимание запроса"?
Логически дублированные/эквивалентные части вычленять, например. Это без переводя на язык реляционной алгебры и невозможно толком. А если используется view в запросе вместе в дублированием части её тела, то на клиенте тем более невозможно.
Здравствуйте, IB, Вы писали:
IB>Здравствуйте, gandjustas, Вы писали:
G>>Покажи пример где EF последней версии генерит неэффективный запрос.
IB>
IB> Order[] orders = context.Set<Order>().Include( o => o.Products).ToArray();
IB>
IB>Генерится SQL, который в два раза менее эффективен, чем генерил в свое время linq2SQL. И это один из наиболее частых сценариев, то есть это приговор инструменту...
IB>А знаешь почему запрос такой тормозной и они так и не поправили его за пять лет? Потому что для корректной работы маппинга EF через внутреннюю модель, нужно сгенерить дополнительный столбец, по которому не построишь индекс, а потом еще и отсортировать по этому столбцу. IB>То есть нельзя просто взять и поправить генерацию запросов для сценария потомок-родитель — нужно переделывать всю архитектуру генерации запросов. А эта архитектура, в свою очередь, явилась следствием дурацкой идеологии. IB>Как видишь, иногда полезно все-таки понимать изначальную идею решения и оценивать ее адекватность, а не бросаться сразу осваивать все что предложили.
Вы имеете в виду наследование и столбец-дискриминатор? Если да, то по примеру у вас этого вообще не видно.
Напишите что за схема используется и какой SQL получается в обоих случаях.
PS. Не сравнивал эффективность, но способность EF6.1 загружать несколько связанных коллекций (OtM, MtM) одним запросом меня порадовала. Hibernate насколько я знаю до сих пор это не осилил и плюётся исключением.
Здравствуйте, gandjustas, Вы писали:
IT>>В общем, если бы я точно знал куда я лезу, когда начинал заниматься linq-провайдером в BLT, то точно бы не стал этого делать и сейчас, скорее всего восхвалял EF вместе с тобой и точно так же спорил бы с IB G>А почему? Решение проблем не стоит затраченных усилий?
Потому что я недооценил сложность задачи. Причём недооценил не просто скажем в пару раз, а как оказалось в пару десятков раз. Планировалось всё закончить за пару тройку месяцев, в результате где-то только через пол года наступило понимание происходящего. Естественно, речь идёт не о full-time работае за деньги, а об open-source проекте в свободное время, но даже работая full-time такая задача не поднимается за несколько месяцев.
G>Тогда за что EF ругают?
За громоздкую и никому не нужную архитектуру. За тормоза. За кривой SQL. За кривой маппинг, вспомним маппинг энумераторов. За бестолковые решения, делающие некоторые фичи совершенно бесполезными. Самое интересное, что на уровне архитектуры решаемая задача на самом деле проста как угол дома. Если рисовать квадратики подсистем, то их можно будет пересчитать на пальцах одной руки. Всё, что нужно было сделать команде EF — это посмотреть по сторонам и проанализировать существующие решения на предмет наличия решений и их полезности. Тем более, что у них уже был собственный неудачный опыт ObjectSpaces и ошибочный на уровне архитектуры, но качественный в реализации Linq2SQL. Главной ошибкой было, конечно же, создание архитектуры на базе никому не нужных сервисов тяжёлой ORM.
IT>>Я программист, а не пиарщик. Видимо в этом проблема. К тому же см. выше про ресурсы. Кто-то их тратит на написание кода, а кто-то на толпы восторженных пользователей. G>Без реального фидбека хороший продукт не получится. А фидбек получить без контента не получится.
Фидбека хватает. linq2db не делался на голом месте. Можно сказать, что это глубокая переработка BLToolkit в части работы с БД, в которой учтены недостатки и переписаны проблемные места последней. К тому же, в отличии от команды EF, которая пишет продукт для кого-то, linq2db делается в том числе и для себя. У MS (и не только) традиционно хорошо получаются лишь те продукты, которыми они пользуются сами. Возьмём тут же студию или WPF, которым стало можно пользоваться лишь после того, как его стали применять в студии.
G>Я не про форум, а про гугл. Главное правило интернета — если тебя не находит гугл, значит тебя не существует.
Как договориться с гуглом я не знаю Видимо на это надо убить всё свободное время, но тогда кто будет заниматься библиотекой?
G>Генерит имя класса DataBaseName.WithDot, что вызывает ошибку компиляции.
Поправлю. Хотя это всё можно настроить в самом шаблоне, но исправить надо.
IT>>Всё можно сконфигурировать и без конфигов. Последние пять лет у меня это вообще была единственная доступная опция. G>Нельзя передать в конструктор контекста строку подключения
public DataConnection(IDataProvider dataProvider, string connectionString)
Здравствуйте, Ночной Смотрящий, Вы писали:
V>> Когда приводят примеры именно крутости Linq в том плане, что он позволил построить сложный запрос, в котором на SQL сам чёрт ногу сломит, то приводят именно встроенный синтаксис НС>Это личные примеры того кто приводит. Я здесь приводил примеры без этого. И вообще, кто и что приводит к обсуждению отношения не имеет.
Некий AVK приводил.
Не знакомы?
V>>А в приведенном тобой виде, повторюсь, мы могли это еще в 2004-м. )) НС>Подобные утверждения выдают твое полное непонимание того, что такое LINQ. Без expression tree LINQ невозможен в принципе.
Пффф...
НС>>>Похожесть тебе только показалась. Ключевой момент здесь — наличие expression tree, которого в 2004 не было. А QC это так, мелочевка. V>>Это у вас не было. НС>Это в C# не было.
Это было у нас.
V>> А у нас — практически все используемые по-факту операции в выражениях T-SQL. И переопределение операторов, ес-но, для вменяемого синтаксиса. НС>Ты не понимаешь что такое expression tree.
У нас называлось SqlOrOp, SqlAddOp, SqlJoinOp. И переопределение операторов в рамках C# отчасти выручало.
НС>>>За счет того что выкидывается куча странного кода внутри хранимок. Особо весело выходит, когда одна хранимка вызывает другую, та третью и т.д. V>>Так это специально так делается.
НС>О да, и специально от этого тормозит как не в себя. Потому что вызов хранимки в интерпретаторе SQL это дорого, и потому что средства декомпозии у SQL до жути убоги (из нормального в mssql, по сути, только inline functions).
Временная таблица уровня транзакции тебе в помощь для декомпозиции.
НС>>>Во-во, навертят бреда вокруг промежуточных таблиц на ровном месте с десятком select into, а потом оказывается что все можно переписать без них. V>>До снятия ограничений с табличных ф-ий на рекурсию и до введения рекурсивных возможностей в SQL — нифига не всё.
НС>Описываемые мной проблемы присутствовали без какой либо рекурсии.
Без рекурсии не нужны были временные таблицы.
V>>Опять же. В любом случае, в процессе таких же точно вычислений точно так же создаются промежуточные результаты во временных таблицах, просто неявно. НС>Вот только перформанс с их выкидыванием, напоминаю, улучшался в разы.
Тут бы хотелось взглянуть на до и после. Бо эксперименты с рекурсивными возможностями показали, что особой разницы с аналогичным кодом на курсорах нет.
V>>А код с промежуточными результатами зачастую намного проще и, опять же, замечательно поддаётся декомпозиции и повторному использованию. НС>Код LINQ запросов неизмеримо лучше поддается декомпозиции, чем императивный код на T-SQL.
На стороне клиента. База его компилит каждый раз.
V>>А какой смысл многократно расписывать одни и те же комбинации джоинов? НС>А не надо, внезапно, в LINQ расписывать руками джойны, представляешь?
Компилятору запроса на стороне базе надо. Тут речь идет о сравнительной стоимости стадий собсно подготовки запроса и его исполнения. Для частых однострочных обновлений прямой вызов sp в синтаксисе {proc params..} заруливал всё и вся. Стадия компиляции запроса отсутствует.
Здравствуйте, gandjustas, Вы писали:
V>>Т.е. ты сам себе ПМ, аналитик, архитектор и тот самый Вася, если тебе через 10 мин (!!!) потребовалось третье поле. )) G>Как это связано? Чтобы добавить поле нужен аналитик, архитектор и еще кто-то?
Ха-ха три раза.
Сначала код, так?
Например, для среднеразмерной складской программы?
V>>Худшие архитектурные решения получаются у людей, чей кредит доверия превышает их профессиональные навыки, а всё остальное — лирика и субъективизм.
G>На поле СУБД часто наблюдаются искажения. Человек знающий слово "статистика", "хинт" или "покрывающий индекс" получает практически неограниченный кредит доверия со стороны тех, кто подобных слов не знает.
Какое-то зазеркалье.
G>Причем если бы вместо СУБД был функциональный язык, то его бы послали и запилили все на "родном" C#\Java\PHP. Но СУБД такая штука, что отказаться от неё нельзя, а вникать как она работает всем не хочется (выводит из зоны комфорта).
Зона комфорта, говоришь? ))
Вас ведь именно за лень ума и ругают (если посмотреть на все эти споры с высоты птичьего полёта), а ты так подставляешься.
G>Вот и получается, что DBA с посредственными навыками получают слишком большой кредит доверия. G>Кстати по этой же причине последние годы появилось повальное увлечение NoSQL базами. Они банально проще и работа с ними более прямолинейна.
И кто тут косностью страдает?
NoSql хорош не по этому, а потому что аппаратура позволяет отказаться от реляционки. В т.ч. быстродействующие внешние носители, а не только размер ОП. Сдаётся мне, ты фундаментально не понимаешь происходящих процессов.
Реляционка с построчным хранением — самая неподходящая структура для навигации в случае наличия данных в ОП. Хуже — не придумать. И самая лучшая для МЕДЛЕННЫХ внешних носителей из всех имеющихся на сегодня конкурирующих парадигм. Поэтому и сложность алгоритмов в реляционках до сих пор считают в попугаях, то бишь, в кол-ве "страниц", необходимых для сканирования. В обычных объектах для этого же существуют "жесткие" ссылки, завязанные на физическое представление данных в памяти, где операция перехода по ссылке сравнима с разыменованием указателя... что на 4-8 порядков быстрее, чем поиск по ключу в реляционке.
Здравствуйте, vdimas, Вы писали:
V>Т.е. ты сам себе ПМ, аналитик, архитектор и тот самый Вася, если тебе через 10 мин (!!!) потребовалось третье поле. ))
Как это всё связано вместе?
V>Такого рода задачи у нас тоже бывали, но ничего серьезного обычно, т.е. проекты сами несерьезные, обсуждать бессмысленно. Из подобного наколенного творчества делать какие-либо выводы я бы не стал, хотя сам именно в таком режиме много чего понаделал.
Не совсем понял понял как добавление третьего поля в форму связано с серьёзностью проекта, ну да фиг с ним.
V>Дай-ка угадаю, чтобы мы этот твой аргумент (уже не первый раз тобой приведенный за последние годы, кста), "проехали", наконец. V>Ты плотно работаешь в команде не более 3-х человек?
И в таких командах мне доводилось работать тоже. Если эти 3 человека "Чаки Норисы" и смогли между собой договориться, то по эффективности такая команда может легко порвать на тряпки два десятка обычных девелоперов. Но, к сожалению, такие команды сегодня большая редкость прежде всего по причине неумения менеджментом их создавать и ими управлять. Проще нанять двадцать человек, всё по максимуму зарегулировать и после этого обозвать проект "серьёзным".
В такой команде (из 3-х человек) я работал до текущего проекта. Сейчас у меня в команде 7 или 8 (не знаю точно сколько в Индии) дотнетчиков, 5 мейнфремщиков, 5 аналитиков, пара DBA. Эффективность работы весьма низкая. Уровень дизайна и архитектуры плачевный. Сейчас мы эту ситуацию выправляем. Мне за пол года удалось отогнать от базы всех DBA и фактически узурпировать дизайн БД, полностью отказаться от спроков и прямого SQL и перевести .NET разработку полностью на linq. Сразу стало легче дышать всем. А уж как народ удивляется вдруг возросшей производительности!
V>Т.е. независимо от кол-ва людей в конторе, плотно по работе у тебя максимум пара коллег контактирует в каждом проекте. Другая организация труда тебе будет просто раздражать, ты работать по-другому не будешь и продуктивно не сможешь при всем желании.
Это не так. Мне в мою бытность контрактником доводилось работать на разных проектах. В том числе, где количество девелоперов было около 60-70-ти человек. Это был по всей видимости твой любимый тип проекта. Куча BA, архитекторов и ПМ-ов. Супердорогой проект для заказчика. Но я понимаю почему. IBM в обмен на собственный бренд и гарантии успеха раздевал заказчика практически до трусов. Это мне понятно. Но зачем раздевать до трусов самого себя я не понимаю. Поэтому, стараюсь избегать подобных проектов. Хотя похоже всё-таки опять вляпался.
V>Речь была о специфике конкретной БД. Иначе зачем нам ДБ-разраб, когда дело касалось бы "голого SQL"?
Как раз с помощью linq можно очень неплохо учитывать специфику конкретной БД. Гораздо лучше чем это делают DB-guys.
V>Косность мышления — это почти врожденное кач-во человека
Это не так. Врожденные качества человека — это максимум треть. Ещё треть — это воспитание (образование). Оставшаяся часть — окружение, в котором человек пребывал/пребывает.
У DBA очень специфическое и весьма консервативное окружение. При всей их экстравертности это окружение лекго её компенсирует и в конце концов подавляет. Ещё раз повторюсь. Худших архитекторов, чем выросших из DBA я в своей жизни не видел. При этом, подозреваю, что это как раз та лучшая часть, которая смогла в определённой степени преодолеть свою костность. На самом деле это всё легко объясняется без всякого выпендрёжа. SQL весьма специфичный и главное консервативный инструмент. А тот же C# как язык программирования общего назначения даёт программисту в руки на порядок более широкий спектр парадигм, паттернов и прочих инструментов. В результате и C# девелоперы обзаводятся более широким кругозором, разнообразными знаниями, умением видеть проблему под разными углами.
V>А я видел худшие архитектурные решения от "программистов от сохи", и?
Не спорю, криворучки везде встречаются. Но хороший дизайн от бывшего DBA — это редкое в природе и можно сказать аномальное явление, которое мне пока не посчастливилось видеть ни разу.
V>Худшие архитектурные решения получаются у людей, чей кредит доверия превышает их профессиональные навыки, а всё остальное — лирика и субъективизм. Я наблюдал, что тот же самый человек, но уже с адекватным кредитом доверия, порождает потом неплохие в итоге решения, потому что из работы выключен банальный личный снобизм. Человек был ВЫНУЖДЕН быть открытым и любопытным. Что дало требуемые плоды. Всё-таки все плохие решения идут обычно от недостатка информации и ни от чего более. (Малый опыт я не рассматриваю, бо бесполезно в этом споре)
Ты как раз зря не рассматриваешь опыт. У того же DBA опыт прежде всего однобокий, другими словами малый во многих областях. В рузультате и получаются однобокие решения.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, vdimas, Вы писали:
НС>>В BLT определенные оптимизации делаются. V>В рамках логических/арифметических выражений?
Почему такое условие? И о каких конкретно выражениях речь (в сиквеле, в отличие от универсальных языков, 3 типа выражений, а не один)?
V>>>, то бишь без "понимания" самого запроса НС>>Что такое "понимание запроса"? V>Логически дублированные/эквивалентные части вычленять, например.
Это без проблем с expression tree делается. Есть ли в конкретном провайдере такая оптимизация и насколько она вообще нужна — этот вопрос надо изучать отдельно.
V>А если используется view в запросе
Ну вот и не надо использовать view, если не нужны индексы по нему. А если индексы нужны, то и сиквел у себя уже ничего заинлайнить не сможет.
Здравствуйте, vdimas, Вы писали:
НС>>Это в C# не было. V>Это было у нас.
Пффф (С)
НС>>Ты не понимаешь что такое expression tree. V>У нас называлось SqlOrOp, SqlAddOp, SqlJoinOp. И переопределение операторов в рамках C# отчасти выручало.
Ты не понимаешь что такое expression tree. Это не просто способ конструирования дерева (тем более что дерево там совсем не 1 в 1 срезультирующим сиквелом), это еще и полная проверка компилятором, и полноценная работа всех средств анализа, рефакторинга и навигации.
V>Временная таблица уровня транзакции тебе в помощь для декомпозиции.
Во-во, вот после таких декомпозиций и начинаются жуткие тормоза. Иногда отдельные DBA так надекомпозируют, что выборка пары десятков строк занимает минуту.
НС>>Описываемые мной проблемы присутствовали без какой либо рекурсии. V>Без рекурсии не нужны были временные таблицы.
Вот я и говорю что не нужны. А были. В количестве. DBA блин, ему ж все заинкапсулячить надо в хранимки, даже то что следует делать на клиенте.
НС>>Вот только перформанс с их выкидыванием, напоминаю, улучшался в разы. V>Тут бы хотелось взглянуть на до и после.
NDA.
V> Бо эксперименты с рекурсивными возможностями показали, что особой разницы с аналогичным кодом на курсорах нет.
Нет там рекурсии. От слова "совсем".
НС>>Код LINQ запросов неизмеримо лучше поддается декомпозиции, чем императивный код на T-SQL. V>На стороне клиента. База его компилит каждый раз.
Нет, не каждый раз. Сиквел прекрасно умеет кешировать скомпилированные запросы. Причем уже давно. Это ж, блин, азы.
Здравствуйте, vdimas, Вы писали:
V>И кто тут косностью страдает? V>NoSql хорош не по этому, а потому что аппаратура позволяет отказаться от реляционки. В т.ч. быстродействующие внешние носители
Ха-ха три раза (С). Основной сценарий NoSql это кластеры, соединенные обычным ethernet и общающиеся по обычному TCP.
НС>Сто такое "синтаксис LINQ"? Если ты про query comprehension, то это не обязательная и даже не основная его часть. Я, к примеру, ей вообще не пользуюсь.
Т.е. ты не пишешь больше 3-х join-ов? Посмотри во что query comprehension разворачивается при большом количестве join-ов. Писать такое без query comprehension практически нереально.
После этого заявления возникает вопрос, у кого запросы сложные, а у кого простые...
И не надо говорить, что ассоциации решают, join-ы не только по ассоциациям бывают.
IT>Кстати, BLT и linq2db поддерживает параноидальный режим описания метаданных БД в виде интерфейсов, а не классов, что вообще искючает создание экземпляров объектов модели данных. Т.е. модель данных используется исключительно для запросов к БД.
Как в этом режиме выглядят insert и update?
Здравствуйте, Alexander Polyakov, Вы писали:
AP>Т.е. ты не пишешь больше 3-х join-ов?
Явных? Очень редко.
AP> Посмотри во что query comprehension разворачивается при большом количестве join-ов. Писать такое без query comprehension практически нереально.
Все реально.
AP>После этого заявления возникает вопрос, у кого запросы сложные, а у кого простые...
У меня длиннее, не переживай.
AP>И не надо говорить, что ассоциации решают, join-ы не только по ассоциациям бывают.
Не только. Но так чтобы не по ассоциациям, да еще больше трех штук в одном запросе — редко.
IT>https://github.com/linq2db/linq2db/commit/c2e3e660c3ffaa7f932772c41088644060b1d6ef IT>Резултат тот же. Может у тебя не самая свежая версия. Я довно nuget не обновлял. Может в этом проблема.
Ну так разберись, где там у тебя старая версия или еще какие косяки. Я вчера сделал всё как указано на сайте проекта. Воспроизведи багу (тебе всё дали для этого) и напиши точную причину, а не гадай на кофейной гуще.
Здравствуйте, Ночной Смотрящий, Вы писали:
V>>И кто тут косностью страдает? V>>NoSql хорош не по этому, а потому что аппаратура позволяет отказаться от реляционки. В т.ч. быстродействующие внешние носители
НС>Ха-ха три раза (С). Основной сценарий NoSql это кластеры, соединенные обычным ethernet и общающиеся по обычному TCP.
Ну продолжай. В кластерах же бывают разные принципы разделения данных.
Здравствуйте, vdimas, Вы писали:
V>В тех проектах, где я участвовал и был выделенный программист БД, кол-во хранимок+сохраненных запросов было порядка 2к на примерно полторы-две сотни таблиц.
Поражаюсь твоему умению представлять худшие из преданных анафеме практик в полубожественном свете
Если нам не помогут, то мы тоже никого не пощадим.