Здравствуйте, adontz, Вы писали:
A>Здравствуйте, gandjustas, Вы писали:
A>>>Нет, это генерация run-time или одноразовая типа add reference. Я о compile-time генерации говорю. G>>О генерации чего вы сейчас говорите?
A>Как схемы БД, так и кода для работы с БД. Да, вот забыл упомянуть, что делать с row level security? Боюсь, если хранимки не генерировать, будет беда.
тогда метаинформация нужна по мощности сравнимая с SQL, такое могут еще нескоро придумать. Может быть MSовский Oslo таким будет.
Здравствуйте, MozgC, Вы писали:
MC>Здравствуйте, IT, Вы писали:
IT>>Временные таблицы точно также затрудняют анализ скрипта, но с ними всё же как-то можно бороться. MC>Вообще временные таблицы иногда могут помочь упростить запрос.
Здравствуйте, adontz, Вы писали:
G>>Сам факт обработки некоторой выборки уже относится к BL, для DAL достаточно вернуть выборку в удобном для обработки виде.
A>Так, ещё раз. Если я говорю "Найди мне клиента по имени Иван" (FindByFirstName), а Вани нет, то это нормальная ситуация. Если я говорю, "верни мне клиента с идентификатором {356F893B-68B3-4687-906B-0A50DD1612C1}" (GetById), а клиента с таким идентификатором нет, то что-то очень серьёзно не так, потому что нарушена целостность данных. Например, заказ ссылается на клиента через идентификатор, а клиента с таким идентификатором нет. Сохранение ссылочной целостности данных в компетенции DAL. Нельзя стирать клиента на которого оформлены заказы. Поэтому GetById, если ничего не найдено, выкидывает исключение. Про orphan records слышал?
Это нормальная/ненормальная ситуация не для БД и даже не для DAL, а для гораздо более высокоуровневой логики.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, gandjustas, Вы писали:
A>>Linq не работает не с бизнес-сущностями, а с DTO. G>Linq работает с данными, или с записями если угодно (одно и тоже). DTO — костыль для изначально хреновой жирной модели.
Я предпочитаю называть набор классов, соответсвующих схеме БД моделью данных приложения. Как правило этот термин интуитивно понятен большинству, не противопоставляет себя объектной модели приложения и не вызывает бурных возражений
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, gandjustas, Вы писали:
G>>Само наличие индектов еще не сделает запрос супербыстрым. A>Зная какие есть индексы, можно предсказать какие выборки будут супербыстрыми. Никакой магиитут нет.
Нельзя в принципе. Даже сама СУБД не умеет так.
Думаешь почему есть Estimated Execution Plan, а есть реальный план исполнения запроса?
Пожно только предположить, а это как раз преждевременная оптимизация, которая ни к чему хорошему не ведет.
G>>Кстати как будете обеспечивать синхронность базы и кода у клиента? Вдруг "грамотный" админ залезет в базу и грохнет индекс? A>А что, ваш метод защищает от "грамотного" админа? Да и вообще, насколько актуальна эта проблема?
Мой метод не защищает, и не дает иллюзию защиты, в отличие от ...
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, gandjustas, Вы писали:
A>>>Linq не работает не с бизнес-сущностями, а с DTO. G>>Linq работает с данными, или с записями если угодно (одно и тоже). DTO — костыль для изначально хреновой жирной модели.
IT>Я предпочитаю называть набор классов, соответсвующих схеме БД моделью данных приложения. Как правило этот термин интуитивно понятен большинству, не противопоставляет себя объектной модели приложения и не вызывает бурных возражений
Я тоже так предпочитаю называть, только у многих модель данных ассоциируется с domain model, что приводит у ненужному терминологическому спору.
Здравствуйте, adontz, Вы писали:
A>Влад, ты рассуждаешь так, как будто кроме DAL ничего нет.
О. Ты будешь потрясен. Я рассуждаю так, как будто DAL больше не нужен. Это еще прикольнее .
Зачем мне DAL если я пользуюсь типизированными запросами? Чем в этом случе DAL отличается от бизнес-логики?
A>Что потом делать с твоими анонимными типами?
Обрабатывать. Наворачивать над данными сложную логику вовсе не обязательно. Те же запросы могут решить задачи в сто раз проще.
Возьмем к примеру этот сайт. Зачем мне делать какие-то бизнес-объекты чтобы отобразить информацию о сообщениях форума? А зачем бизнес-объекты чтобы вывести список твоих оценок?
VD>>Не надо отображать объекты на БД.
A>О как. И как ты представляешь связь тогда?
Для таблиц использовать простой мапинг один к одному (таблица на один простой объект). Для выборок в которых не требуются все поля из таблицы или требуются поля из разных таблиц использовать кортежи или анонимные типы.
В общем, получать списки данных и обрабатывать их. Если нужны все данные по сущности (в том числе получаемые по вязям), ну, что же создадим запрос с джоинами. Точнее linq позволяет их представить в виде свойств и избежать прямых джоинов, но это уже детали реализации. В тоге все равно будет один комплексный запрос в БД.
В общем, это можно назвать — назад в будущее! Мы как бы возвращаемся в прошлое когда мы писали текстовые запросы к СУБД и обрабатвали их в своем любимом языке, но на новом уровне. Теперь запросы типизированные и нам не нужен ни дал, ни сложные TSQL. Более того. Получив список мы можем продолжить обрабатывать его теми же запросами, но уже локальными.
Задача обработки данных превращается в задачу трансформации данных.
В таких условиях ООП используется скорее для организации логики программы, а не для представления данных.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, MozgC, Вы писали:
MC>Я бы вызвал исключение, а уже бизнес-логика бы решила что делать с тем, что такой темы нет.
Это назвается строить логику на исключениях, практика, за которую нужно не просто отбивать пальцы линейкой, а лучше даже что-нибудь отрезать.
MC>Вообще так можно про все сказать "что тут исключительного". К примеру пытаемся прочитать файл, а такого файла нет (его уже пользователь удалил), ну а что тут исключительного, давайте признак возвращать.
Вот хороший пример. Можно ещё обсудить вариант с разрешением к доступу к файлу. Твой backup процесс пытается скопировать файл, а он недоступен, по твоей логике есть только один путь — кинуть исключение и прервать процесс. Такой бекапер будет выброшен сразу же после первой проблемы с потерей информации.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
MC>>Я бы вызвал исключение, а уже бизнес-логика бы решила что делать с тем, что такой темы нет. IT>Это назвается строить логику на исключениях, практика, за которую нужно не просто отбивать пальцы линейкой, а лучше даже что-нибудь отрезать.
Нет, это называется использовать исключения там где нужно.
MC>>Вообще так можно про все сказать "что тут исключительного". К примеру пытаемся прочитать файл, а такого файла нет (его уже пользователь удалил), ну а что тут исключительного, давайте признак возвращать. IT>Вот хороший пример. Можно ещё обсудить вариант с разрешением к доступу к файлу. Твой backup процесс пытается скопировать файл, а он недоступен, по твоей логике есть только один путь — кинуть исключение и прервать процесс. Такой бекапер будет выброшен сразу же после первой проблемы с потерей информации.
Нет, по-моему логике такого не будет, не надо за меня говорить. По-моему логике при попытке скопировать файл выкинется исключение а бизнес-логика решит что делать дальше, к примеру повторить попытку позже или залогировать это или сообщить пользователю.
Здравствуйте, VladD2, Вы писали:
VD>Задача обработки данных превращается в задачу трансформации данных. VD>В таких условиях ООП используется скорее для организации логики программы, а не для представления данных.
Не-не-не, дэвид блейн, не-не. Не надо ООП тянуть в организацию логики программы. Для логики подходит модель SOA.
Всля логика разбивается на сервсиные классы, которые в идеале stateless, в качестве SOA-интерфейсов используются интерфейсы языка, в качестве брокера — IoC контейнер. Методы сервисов создают цепочку вызовов, которая формирует запросы, не материализуя их без необходимости.
IoC контейнер в возможностями перехвата (runtime AOP) позволяет также навешивать авторизацию, кеширование и другие вкусности без затрагивания логики.
Здравствуйте, MozgC, Вы писали:
MC>Я бы вызвал исключение, а уже бизнес-логика бы решила что делать с тем, что такой темы нет.
Это реализация логики на исключения. Нужны объяснения почему — это плохо?
MC>Вообще так можно про все сказать "что тут исключительного". К примеру пытаемся прочитать файл, а такого файла нет (его уже пользователь удалил), ну а что тут исключительного, давайте признак возвращать.
Так и есть. Если это файл документа в текстовом процессоре, то кидать исключения — это неверная политика. Это и есть реализация логики на исключениях.
А если это конфигурационный файл который кто-то случайно стер, то исключение будет весьма к месту. Только обрабатывать его надо не в прикладном коде, а где-то в функции Main(), чтобы приложение сообщило о проблеме и тихо завершилось. В других случаях это может быть цикла обработки сообщений, чтобы при исключении в обработчике одного из них была выдана ошибка и можно было бы попытаться выполнить другую команду.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, MozgC, Вы писали:
MC>>Я бы вызвал исключение, а уже бизнес-логика бы решила что делать с тем, что такой темы нет. IT>Это назвается строить логику на исключениях, практика, за которую нужно не просто отбивать пальцы линейкой, а лучше даже что-нибудь отрезать.
Удели пожалуйста 2 минуты, объясни почему за выбрасывание исключения из DAL при отсутствии темы с заданным ID нужно что-нибудь отрезать.
PS. "По-моему логике" выше это я прикольно написал, видимо спать пора
Здравствуйте, VladD2, Вы писали:
MC>>Я бы вызвал исключение, а уже бизнес-логика бы решила что делать с тем, что такой темы нет. VD>Это реализация логики на исключения. Нужны объяснения почему — это плохо?
Здравствуйте, adontz, Вы писали:
A>Сам факт модерирования исключителен
Да, ну? А может это вопрос той самой бизнес-логики?
VD>>Почему нельзя сделать метод или запрос который просто вернет некий признак отсутствия данных?
A>По-моему, в твоём примере налицо race condition. Надо либо запретить удалять из базы данных (я за этот метод), а только помечать сообщение как удалённое, либо смириться с тем что DAL кинет исключение, потому что блокировать ресурс-сообщение нельзя. В BL его можно обработать, а можно даже не обрабатывать. В конце концов я могу прямо в URL вбить номер несуществующего сообщения.
Зачем мне мериться? Проще возвращать что надо и проверять результат.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, MozgC, Вы писали:
MC>Здравствуйте, IT, Вы писали:
IT>>Здравствуйте, MozgC, Вы писали:
MC>>>Я бы вызвал исключение, а уже бизнес-логика бы решила что делать с тем, что такой темы нет. IT>>Это назвается строить логику на исключениях, практика, за которую нужно не просто отбивать пальцы линейкой, а лучше даже что-нибудь отрезать.
MC>Удели пожалуйста 2 минуты, объясни почему за выбрасывание исключения из DAL при отсутствии темы с заданным ID нужно что-нибудь отрезать.
Не нужно ничего отрезать. Вообще вопрос правильности кидания исключений — исключительно вопрос веры.
Если вы верите что ненахождение чего-либо по ИД в базе — всегда исключительноая ситуация, то ваш подход верен.
Но у вас обязательно возникнет ситуация, когда эта ситуация будет вполне нормальной в одном случае и ненормальной в другом.
Тогда у вас будет или два метода — один — бросающий исключение, а другой такой же, но небросающий. Или у вас появится метод BL, где половина кода в try, другая половина в catch, при этом реально достаточно одного простого if.
Короче если ваша вера непральная, то вы сами себе что-нить отрежете.
Здравствуйте, gandjustas, Вы писали:
G>Не нужно ничего отрезать. Вообще вопрос правильности кидания исключений — исключительно вопрос веры. G>Если вы верите что ненахождение чего-либо по ИД в базе — всегда исключительноая ситуация, то ваш подход верен. G>Но у вас обязательно возникнет ситуация, когда эта ситуация будет вполне нормальной в одном случае и ненормальной в другом. G>Тогда у вас будет или два метода — один — бросающий исключение, а другой такой же, но небросающий. Или у вас появится метод BL, где половина кода в try, другая половина в catch, при этом реально достаточно одного простого if.
Пока такой ситуации не возникало.. Но у меня за плечами на порядок меньше опыта чем у вас всех.
G>Короче если ваша вера непральная, то вы сами себе что-нить отрежете.
Понятно. Не нужно думать что я везде исключения кидаю, но просто вот в приведенных 2х примерах выкинул бы и обработал выше.
Я конечно не утверждаю что это правильно, не мне с вами всеми спорить, просто я не вижу в этом проблемы. Будет полезно если мне кто-то объяснит эту самую проблему, желательно как раз на примере с выбрасыванием исключения из DAL при ненахождении записи по ID и последующей обработке в BL — что в этом такого ужасного? (видимо теперь этот вопрос в IT & VladD2)
A>JOIN тут никак не поможет. Объясняю данный пример подробно. Есть таблицы А и B вида A>
A>id | name
A> 1 | first
A> 2 | second
A> 3 | third
A>
A>а так же таблица A2B вида A>
A>aId | dId
A> 1 | 1
A> 1 | 2
A> 2 | 1
A> 2 | 3
A> 3 | 1
A> 3 | 5
A>
A>Если читать её не целиком, а кусками (не важно по aID будет выборка или по bID) ты в самом лучшем случае замедлишь всё в O(ln(n)) раз.
Я уже устал от бесполезных разговоров. Что помешает сделать джоин? И зачем выбирать эти данные (в чем задача?)?
A>Затем чтобы, например, прибайндить IBindingList<мои объекты> сразу в несколько View. И чтобы они обновлялись нормально, без "паркинсона" на кнопке F5, а для этого, кстати, нужен INotifyPropertyChanged и вообще много разных мелких инфраструктурных штучек. А ещё, могу захотеть кешировать, причём даже не весь объект, а его часть. Если чтение производится где попало через Query, мне это вряд ли удасться сделать.
А, да, да... Каширование. Туча не нужной обвески и все это ради веры в объекты там где им не место.
А зачем, собственно? Мы ведь должны были выбрать список тем для форума. Или данные по клиенту.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, gandjustas, Вы писали:
A>>Если читать её не целиком, а кусками (не важно по aID будет выборка или по bID) ты в самом лучшем случае замедлишь всё в O(ln(n)) раз. G>А с какой целью её читать вообще?
В моём случае, для подсказок при вводе данных.
A>>Затем чтобы, например, прибайндить IBindingList<мои объекты> сразу в несколько View. И чтобы они обновлялись нормально, без "паркинсона" на кнопке F5, а для этого, кстати, нужен INotifyPropertyChanged и вообще много разных мелких инфраструктурных штучек. А ещё, могу захотеть кешировать, причём даже не весь объект, а его часть. Если чтение производится где попало через Query, мне это вряд ли удасться сделать. G>View, f5... надеюсь это не о вебе.
Нет. F5 вообще общепринятАя клавиша для операции вроде refresh.
Здравствуйте, gandjustas, Вы писали:
A>>Как схемы БД, так и кода для работы с БД. Да, вот забыл упомянуть, что делать с row level security? Боюсь, если хранимки не генерировать, будет беда. G>тогда метаинформация нужна по мощности сравнимая с SQL, такое могут еще нескоро придумать. Может быть MSовский Oslo таким будет.
Если не пытаться генерировать совсем всё-всё-всё, метаинформация может получится довольно таки простой.