Здравствуйте, Terix, Вы писали:
T>Может и тупик, но проблема эта — не проблема ORM. Это проблема языков, которые требуют на любой чих делать отдельный класс.
Нет. Это проблема — именно ORM. Потому что без ORM мы на тех же языках работаем с рекордсетами, которые не требуют порождать по классу на запрос. И прекрасно биндим их хоть в UI, хоть в бизнес-логику.
ORM претендуют на какую-то помощь, которой по факту не оказывают.
T>Это и есть кеш, да. Но сущности попадут в кеш независимо от того, как их загрузили — lazy или eager. Поэтому проблема возникает не из-за lazy load.
Eager load существует только как костыль к lazy load.
Напомню, что в обычном приложении до-ORMной эпохи нет никаких Eager Load — мы просто выполняем запрос и получаем результат. У нас нету "отображаемых объектов" с навигационными свойствами, которые, собственно, и провоцируют кэш, lazy load, и eager load, который должен изображать закат солнца вручную.
T>Ну я говорю ORM и имею в виду в первую очередь Hibernate. Так это не единственная альтернатива. А что ты имеешь в виду? Какие ORM?
Ну, EF. А что, в Hibernate уже появился способ сделать
update stock set remainingQuantity=remainingQuantity-orderLine.orderedQuantity from select id, remainingQuantity from stock inner join orderLine on orderLine.stockItemId = stock.itemId where orderLines.OrderId = @orderID ?
И всё это дружелюбно к кэшу и всё такое?
Я на него много лет не смотрел
T>Да, повлияло, да уронило, да это проблема lazy load, но не та, про которую ты вначале говорил. Когда заранее знаешь, что lazy load мешает — надо включить eager.
Требование "знать заранее" напоминает мне старую сказку про порошок от блох — который надо сыпать в глаза каждой блохе.
Автоматический инструмент должен решать проблемы, а не создавать их. Требование вручную размечать код для устранения боттлнеков противоречит самой идее абстрагирования
T>>>то нарвёшься на проблему N + 1. Из-за lazy load.
S>>Надо понимать, что именно такой код не пишут почти никогда. Мы ж программисты — мы делаем Инкапсуляцию! Нужно среднее — добавляем студенту вычисляемое свойство AverageMark, с геттером, который бежит по коллекции StudentMarks.
S>>И биндим к гую вот эту вот коллекцию студентов, где в колонке 1 будет LastName, а в колонке 2 — AverageMark.
T>Я несколько раз написал, что так делать нельзя, когда используешь ORM. Увы.
Так проблема-то в том, что полноценные ORM вообще никакого решения для этого случая не предлагают.
T>Да, всё правда, именно поэтому не надо так делать. Да, абстракция течёт, но ORM не помогают абстрагироваться от БД полностью, они помогают упростить проведение типовых операций. Нутрянку БД при этом по-прежнему надо понимать.
Нет. Теперь надо понимать не только нутрянку БД, но ещё и нутрянку ORM. Ящетаю — в баню таких "помощников".
Вся эта помощь при проведении "типовых операций" сводится к "рисование формы master-detail", что прекрасно работало в Delphi 2 образца 1997 года безо всяких ORM.
T>Вот этот view ты замапишь на сущность в коде и будешь спокойно использовать.
Это хорошая идея. Только теперь у нас логика размазалась между тиерами, и чтобы что-то починить надо собирать вместе спеца по жаве и спеца по SQL.
Если я захочу засунуть логику в SQL, то я обойдусь средствами SQL, а ORM выкину на помойку, т.к. он мне вообще не помогает.
T>Не красиво и не ООПшно, но на то он и ORM.
T>Я считаю, что пока хороших инструментов нет, лучше не прятать базу далеко, во избежание.
Ну, linq2db движется в правильную сторону.