Здравствуйте, gandjustas, Вы писали:
G>Выделенное повеселило. После этого ты еще ругаешь Linq... Лучше не продолжай.
Бесполезно. Понимаешь, когда он эту ерунду писал 3 года назад — ну что, бывает, многие пытаются трехколесные велосипеды изобретать. Но когда он тоже самое пишет сейчас — это уже о многом говорит.
G>>А вот совершенно случайно MessageModel.Origin имеет тип int.
Не скомпилруется. В чем вопрос?
G>>Это кейс эквивалентный тому, что ты написал с помощью Linq.
Нет! Не эквивалентен! В моём подходе такого бреда никогда не будет: ставим в середину цепочки .ToList() и получаем другой результат.
Вот так помаленьку вы и обкрадываете заказчика: бизнес логика почти не менялась, потребовалось только материализовать промежуточный результат. И вы нарвались на геморрой с выяснений косяков "особенностей" конкретной ORM. А геморрой в чем? Либо надо тщательное тестирование с данными, либо это выстрелит на продакшене. С ходу в чем проблема не поймешь, придется бросить все дела и начать копать эту проблему. Это не сравнимо с тем, чтобы перенести текст из одного окна в другой на этапе написании кода, делается на автомате без включения мозга.
G>>Кстати пока писал понял одну вешь ты передаешь new {id} параметром, то есть первый агрумент у тебя имеет тип object. Таким образом ты не можешь формировать объект-параметр вне функции, где вызвается New.
Это и не нужно.
Для точности, параметр имеет тип T.
G>>Ну и стандартная проблема с передачей в SQL значений null.
Решена естественным образом через Option<T>.
G>Любая ручная операция — повышение вероятности ошибки. Я та понял что у тебя руками запускается и CheckAllQueries, и копируется IMessageInfo руками. То есть на каждое изменение запроса нужно два ручных действия. Такого убожества нигде нет. Даже не представляю что надо делать, чтобы это было оправдано. Кстати как вы боретесь с коллизиями имен при генерации проекций?
CheckAllQueries запускается также на тестовой среде автоматом. Ну вы как маленькие, у вас что тестов нету?
Ручные операции не проблема, если дальше идет машинная проверка. Опять как маленькие, выступаете за компайл проверки, а сути ее не чувствуете.
НС>Это библиотечные вещи, на которые один раз пишется тест, отлавливающий все проблемы. Ну и nameof уже на горизонте, так что часть проблем будет скоро устранена.
Это универсально? Если, да, то это уже выложили на github вместе c linq2db? Или вы уже перешли к обсуждению несуществующего решения?
НС>Давай. На каждый запрос куча танцев с бубном — предварительный вариант, компиляция, заведение новых интерфейсов, переделка исходного запроса.
Прошу быть более конкретным и конструктивным. Какую переделку запроса вы имеете ввиду? Я ничего такого не писал.
AP>>В настоящий рантайм ничего такого не просачивается, всё отлавливается на этапе CheckAllQueries. НС>Статический верификатор можно и к LINQ приделать, так что это не повод от него отказываться.
Если скопировать ваше поведение, то мне надо тут поставить ваш любимый смайл
НС>Зато надо вгрызаться в строковый литерал, в котором ни подсветки синтаксиса, ни навигации, ни тултипов, ни интеллисенса.
Для VS2012 был экстеншен для подсветки SQL синтаксиса в строковых литералах. Для VS2013 пока не вышла. Да, с этим проблемы есть, но опять скопирую вас: это не повод отказываться от этого подхода. Даже Dapper получил широкое распространение, а там автоматической проверки запросов нет.
НС>Слегка?
Эмоции зашкаливают?
Здравствуйте, Alexander Polyakov, Вы писали:
G>>>А вот совершенно случайно MessageModel.Origin имеет тип int. AP>Не скомпилруется. В чем вопрос?
Ну да, тут компилятор выругается.
G>>>Это кейс эквивалентный тому, что ты написал с помощью Linq. AP>Нет! Не эквивалентен! В моём подходе такого бреда никогда не будет: ставим в середину цепочки .ToList() и получаем другой результат.
Ну так ты и в Linq ставишь ToList и получаешь другой результат...
А вообще с ToList ты дважды создешь объекты, что удваивает нагрузку на GC и снижает производительность. Идеальный вариант когда материализутся объекты, которые сразу отдаются в генерацию страниц.
AP>Вот так помаленьку вы и обкрадываете заказчика: бизнес логика почти не менялась, потребовалось только материализовать промежуточный результат. И вы нарвались на геморрой с выяснений косяков "особенностей" конкретной ORM. А геморрой в чем? Либо надо тщательное тестирование с данными, либо это выстрелит на продакшене. С ходу в чем проблема не поймешь, придется бросить все дела и начать копать эту проблему. Это не сравнимо с тем, чтобы перенести текст из одного окна в другой на этапе написании кода, делается на автомате без включения мозга.
Не понял, зачем материализовывать промежуточный результат? Это затратно и непонятно зачем, никакого value не несет. А потом еще и чето надо запускать и руками копировать, что обязательно забудут.
И почему с ходу не поймешь проблему что из базы вернулся null, а ты его мапишь на не-null? Это же случается только для чисел и дат, почему вообще в класс view model попадет свойство с типом int, если оно может отсутствовать?
G>>>Ну и стандартная проблема с передачей в SQL значений null. AP>Решена естественным образом через Option<T>.
Покажи пример кода.
Здравствуйте, Alexander Polyakov, Вы писали:
G>>Любая ручная операция — повышение вероятности ошибки. Я та понял что у тебя руками запускается и CheckAllQueries, и копируется IMessageInfo руками. То есть на каждое изменение запроса нужно два ручных действия. Такого убожества нигде нет. Даже не представляю что надо делать, чтобы это было оправдано. Кстати как вы боретесь с коллизиями имен при генерации проекций? AP>CheckAllQueries запускается также на тестовой среде автоматом. Ну вы как маленькие, у вас что тестов нету?
Тесты есть, но Linq таки ловит опечатки в процессе написания. На тесте я могу и реальные запросы прогнать. Заем тогда CheckAllQueries и писать текст.
AP>Ручные операции не проблема, если дальше идет машинная проверка. Опять как маленькие, выступаете за компайл проверки, а сути ее не чувствуете.
Проблема, еще какая, ибо тратится время. Компайл-тайм проверки хороши если работают автоматически. Но с твоей штукой требуется вручную что-то копировать, поэтому и проверку надо вручную запускать.
Здравствуйте, gandjustas, Вы писали:
G>Переписывают не потому что "он крив", а потому что текущая архитектура не позволяет достичь целей.
То есть кривая. Что и требовалось доказать.
G>Раньше позволяла — прикрутили и codefirst, и миграции и производительность поправили.
Да-да, и в итоге получили "... many seldom used features and capabilities in the code base that hamper performance and complicate development" (с)
G>Вообще у тебя проблема с причинно следственными связями. Если нечто криво, то его надо переписать. С этим я согласен. Но обратное в общем случае неверно. Если что-то надо переписать, то это не значит что оно кривое.
Прекрасно! может быть это значит что оно просто не очень прямое? =)))
G>Молодец. Очень профессиональный подход.
Всяко профессиональнее чем в отходах копаться и убеждать всех, что они прекрасны =)
G>Ну хватит врать уже.
Не нарывайся.
G>А кто говорит о полном переписывании ef?
Разработчики и говорят, но ты же идеологию не читаешь. =)
Здравствуйте, IB, Вы писали:
IB>Здравствуйте, gandjustas, Вы писали:
G>>Переписывают не потому что "он крив", а потому что текущая архитектура не позволяет достичь целей. IB>То есть кривая. Что и требовалось доказать.
Странная логика, любая архитектура — набор ограничений. Заранее ты не знаешь какие цели будут поставлены. То есть в принципе любая архитектура кривая.
G>>Раньше позволяла — прикрутили и codefirst, и миграции и производительность поправили. IB>Да-да, и в итоге получили "... many seldom used features and capabilities in the code base that hamper performance and complicate development" (с)
Это слова, всего лишь чье-то мнение, а ты примеры покажи. По факту для типовых применений orm сегодня ef работает отлично, как бы тебе не верилось в обратное. Команда ef поставила очень амбициозную цель — сделать ef единственным средством data access на всех платформах, поэтому у них есть претензии. У тебя и близко таких проблем нет и не будет никогда. Цитирование пресс-релизов никак не ситуацию не исправит.
G>>Вообще у тебя проблема с причинно следственными связями. Если нечто криво, то его надо переписать. С этим я согласен. Но обратное в общем случае неверно. Если что-то надо переписать, то это не значит что оно кривое. IB>Прекрасно! может быть это значит что оно просто не очень прямое? =)))
По твоей логике значит. А вообще не значит.
G>>Молодец. Очень профессиональный подход. IB>Всяко профессиональнее чем в отходах копаться и убеждать всех, что они прекрасны =)
У тебя хоть когда-нибудь факты появятся?
G>>Ну хватит врать уже. IB>Не нарывайся.
Так приводи факты, а не мнение. Твое мнение совершенно ничего не стоит, ты это уже доказал.
G>>А кто говорит о полном переписывании ef? IB>Разработчики и говорят, но ты же идеологию не читаешь. =)
Угу, я исходники читаю. Тебе тоже советую. Пока что все переписывание свелось к копированию code-first почти полностью и выкидыванию objectcontext и связанных классов.
Тебе тоже советую почитать.
Здравствуйте, gandjustas, Вы писали:
G>Странная логика, любая архитектура — набор ограничений. Заранее ты не знаешь какие цели будут поставлены. То есть в принципе любая архитектура кривая.
Ты вообще не понимаешь, похоже, что тебе пишут. Проблема не в том что архитектура кривая, а в том что изначальные цели и требования были сформулированы неверно. А кривая архитектура — лишь следствие.
Ты внимательно почитай что авторы пишут: "there are many seldom used features and capabilities in the code base". Умные люди еще с ранних бета-версий EF говорили именно об этом (посмотри на LINQ часть BLT или linq2db, там почему то этих мегафич нет). Но понадобилось куча времени и релизов, чтобы до разработчиков EF наконец дошло.
Здравствуйте, gandjustas, Вы писали:
IT>>EF — это всё же отдельно от всего лежащий кусок кала. G>Года два назад отдали в ASP.NET
Т.е. его пилят уже не те индусы, которые завалили WinFS?
IT>>Ваня правильнос сказал, что практикующим девелоперам ещё лет 10 назад стало понятно каким должно быть средство работы с БД. Но команда EF шла на пролом своим путём. G>Если всем понятно, то почему никто не сделал?
Во-первых, написание полноценного Linq-провайдера — это не тривиальная задача типа unit testing framework. Лет пять назад в MS эту задачу оценивали в пару лямов. Во-вторых, большинство попыток следуют текущей конъюнктуре и в конце концов сваливаются к созданию heavy-ORM. В-третьих, сделали. linq2db не страдает ORM-ностью и представляет собой скорее типизированный SQL.
IT>>Новый компилятор позволяет переписать устаревший код и сделать его лучше. Но новый компилятор не поможет сделать лучше новую архитектуру. G>Да ладно? Например с помощью compiler as service можно сделать compile time генерация маппинга DataReader на объекты как минимум или запросто компилировать в реальный IL edmx-модель, убрав весь оверхед, или делать compile-time проверяемые текстовые запросы с декомпозицией (как мечтает Поляков).
Убрать весь оверхед не получится. То, о чём ты говоришь — это лишь несколько процентов сценариев использования. Но даже маппинг одного и того же объекта может отличаться. Например:
from t in Table select t;
from t in Table select new { t.Filed1.Length, t };
Во втором случае индексы для маппинга t съедут на 1 и придётся наворачивать весь оверхед обратно. К тому же это всё не является серьёзной проблемой. linq2db строит expression tree для каждого запроса со всеми необходимыми маппингами без всякого оверхеда в run-time, потом компилирует его и кеширует. Эффективность такого решения примерно как у параноидального ручного маппинга с индексами вместо имён полей.
IT>>После прочтения их пресс-релиза у меня уже возникают какие-то смутные сомнения. Особенно по поводу "EF7 is Lightweight and Extensible". G>Ты тоже оцениваешь технологии по пресс-релизам? Лучше посмотри исходники на гитхабе.
Меня очень сильно напрягает слово "extensible". Это плохое слово, если его использовать в самом общем смысле без конкретных пояснений. Обычно решения, в которые пытаются запихнуть расширяемость везде где только можно заканчиваются тем, что приложение всё что может — так это только расширяться и ничего более из полезного.
G>Возвращаясь к теме EF — начиная с версии 5 активно внедряется такой же сервисный подход. Тоже есть встроенный IoC, тоже куча подменяемых сервисов и соглашения (положительное влияние asp.net). Но под капотом там еще остался старый EF, построенный на принципах ООП, который и хотят в версии 7 выкорчевать из EF.
Честно говоря, мне не очень понятно, что там нужно такого расширяемого в linq-провайдере
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Alexander Polyakov, Вы писали:
AP>Мне искренне жаль тех, кто слепо верит в то, что, закрывая SQL linq-ом получается якобы улучшение:
Тебе знаком такой термин — рефакторинг базы данных? Нет? И понятно почему. Рефакторинг БД становится доступен только после использования решений основанных на подобных linq технологиях, т.к. они предоставляют 100%-ный контроль над кодом, работающим с БД.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Честно говоря, мне не очень понятно, что там нужно такого расширяемого в linq-провайдере
Things that are specific to particular types of data stores will be available as extensions that are included as part of the provider. For example, the concept of a model builder that allows you to configure your model will be part of the core framework. However, the ability to configure things such as cascade delete on a foreign key constraint will be included as extensions in the relational database provider.
...
You’ll see the same DbContext/DbSet based API but it will be built over building block components that are easy to replace or extend as needed – the same pattern we’ve used for some of the isolated components we’ve added in recent EF releases.
Здравствуйте, IT, Вы писали:
IT>А в чём тут проблема?
Проблема тут, имхо, в том что психологически человеку некомфортно от того что он не пишет sql руками. А все остальное это попытка обосновать попытку всенепременнейше писать его руками, не смотря на то что это приводит к куче проблем.
IT>Тебе знаком такой термин — рефакторинг базы данных? Нет?
Рефакторинг БД приходилось делать.
IT>... предоставляют 100%-ный контроль над кодом, работающим с БД.
Именно для этих целей и были сделаны методы CheckAllQueries и FindUsages(tableName, columnName=null). CheckAllQueries автоматически генерирует тесты для всех вариантов всех запросов (запуская их в режиме SchemaOnly). Подобные тесты раньше писались вручную для DAL-а. Мне удалось автоматизировать рутинную работу по написанию тестов на DAL.
Здравствуйте, Alexander Polyakov, Вы писали:
AP>CheckAllQueries автоматически генерирует тесты для всех вариантов всех запросов
Тесты это хорошо, но руками править кучу текстовых запросов вместо решарпера при простейшем переименовании поля или таблицы — это надо быть очень убежденным в своей правоте.
Здравствуйте, vdimas, Вы писали:
V>Я вижу, ты страшно далек от понимания того, как подобные задачи решали и решают без LINQ. Обычно в тиме работает человек, специализирующийся на базах и запросах,
Т.е. начинаю я работать над какой-нибудь формой и мне нужно заполнить её данными, пока двумя полями. Я зову Васю-Специалиста-На-Базах-И-Запросах и он пишет мне в моём коде SQL, который читает эти два поля для меня из базы. Через 10 минут мне надо подчитать третье поле, я опять зову Васю-Специалиста-На-Базах-И-Запросах и он мне дописывает SQL по требованию. Потом мне нужно будет добавить четвёртое поле, сделать группировку, чего-нибудь отфильтровать и каждый раз мне нужно будет звать Васю-Специалиста-На-Базах-И-Запросах. Тебе самому не смешно?
V>он умеет SQL намного лучше, чем ты свой C# когда-либо умел или сумеешь.
Хорошее знание SQL — это обязательный скил для разработчика среднего уровня.
V>Ну и понимание происходящего в базе на порядки лучше твоего. Так бывает, когда человек многие годы на чём-то специализируется. )) Поэтому, твоя наивность опять зашкаливает. Если чего-то не знаешь — лучше спросить, ИМХО.
Глубокая специализация имеет две стороны. Положительную — хорошее знание в специализирующейся области. Отрицательную — костность мышления и неприятие любых других технологий.
Худшие архитектурные решение, которые мне доводилось видеть в своей жизни были сделаны людьми, специализирующимися на базах и запросах. Т.к. кроме этого они толком ничего не умееют и не хотят уметь. База данных, это важная, но всё же часть любого приложения, а для них она почему-то всегда не просто часть, а единственная часть приложения. В результате всё остальное приносится в жертву и получается очередное гипертрофированное в сторону БД уродство.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, gandjustas, Вы писали:
G>2) Люди пишут Linq запросы не понимая что происходит в базе. Особенно часто встречается FirstOrDefault, который в SQL работает очень медленно, или банально вызывают функции в предикатах.
Что за проблема с FirstOrDefault?
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, Alexander Polyakov, Вы писали:
IT>>Тебе знаком такой термин — рефакторинг базы данных? Нет? AP>Рефакторинг БД приходилось делать.
И как ощущения? Для меня сегодня рефакторинг БД ничем не отличается от обычного рефакторинга кода. Т.е. вообще ничем. Когда же я писал SQL руками, то это был невероятный геморой.
IT>>... предоставляют 100%-ный контроль над кодом, работающим с БД. AP>Именно для этих целей и были сделаны методы CheckAllQueries и FindUsages(tableName, columnName=null). CheckAllQueries автоматически генерирует тесты для всех вариантов всех запросов (запуская их в режиме SchemaOnly). Подобные тесты раньше писались вручную для DAL-а. Мне удалось автоматизировать рутинную работу по написанию тестов на DAL.
Это ты всего лишь автоматизировал поиск костылей. Linq устраняет сами костыли. Если они у тебя где-то остались, то ты просто не сможешь скомпилировать приложение.
Если нам не помогут, то мы тоже никого не пощадим.