Re[28]: Проблемы организации OR-мапинга
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 19.04.09 13:19
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, gandjustas, Вы писали:


G>>>>Если классы очень похожи, то вполне можно убрать дублирование наследованием.


L>>>Еще и наследование сюда тащить? Нее, ф топку.

G>>А чем наследование плохо?
G>>Общность данных очень удобно выражаать через наследование или реализацию интерфейсов.
L>Прежде всего негибкостью — нет множественного наследования. Во-вторых, нунужным усложнением.
Да и нафиг оно не нужно.
Вполне можно создавать классы, которые содержать чуть больше полей, чем нужно на одной сранице, и использоватть его на многих страницах.

L>>>>>Не один, а пачка: если у кастомера в адресе нужно выбрать город, то здравствуй новая PE с двумя полями ID и Name.

G>>>>Для пар "ключ-значение" уже есть классы.
L>>>Есть, но я не о них. Часто нужно более двух полей, тут то начинают появляться нелепые классы типа CustomerInfo, ContactInfo, etc
G>>Посмотрел свои проекты. По сравнению с случаем выборки пар ключ-значение выборка трех полей из БД осуществляется гораздо реже.

L>У меня другая статистика. У нас оч. тяжелые страницы и много аякса и и потому для каждой сущности, отображаемой на странице, приходится делать ее (сущности) урезаный вариант, а это и приводит в появлению этих ненавистных CustomerInfo, ContactInfo, etc


Может пробема в том, что у вас сами сущности переутяжелены? Хотя CustomerInfo, ContactInfo — тоже неплохой вариант во многих случаях.

Как раз в случаях с Ajax много класов делать не надо. Если передавать на клиента сериализованный в JSON объект, даже класс писать не нужно.
Re[29]: Проблемы организации OR-мапинга
От: Lloyd Россия  
Дата: 19.04.09 13:46
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>Общность данных очень удобно выражаать через наследование или реализацию интерфейсов.

L>>Прежде всего негибкостью — нет множественного наследования. Во-вторых, нунужным усложнением.
G>Да и нафиг оно не нужно.
G>Вполне можно создавать классы, которые содержать чуть больше полей, чем нужно на одной сранице, и использоватть его на многих страницах.

Ну это уже вопрос предпочтений. Я считаю, что если куда-то передали объект, то принимающая сторона на должна знать деталей о том, как этот объект был получен, заполнен ли и он и т.д.

L>>У меня другая статистика. У нас оч. тяжелые страницы и много аякса и и потому для каждой сущности, отображаемой на странице, приходится делать ее (сущности) урезаный вариант, а это и приводит в появлению этих ненавистных CustomerInfo, ContactInfo, etc


G>Может пробема в том, что у вас сами сущности переутяжелены? Хотя CustomerInfo, ContactInfo — тоже неплохой вариант во многих случаях.


Увы, в многих случаях это единственный вариант.

G>Как раз в случаях с Ajax много класов делать не надо. Если передавать на клиента сериализованный в JSON объект, даже класс писать не нужно.


Не, нетипизированные методы идут в топку.
Re[30]: Проблемы организации OR-мапинга
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 19.04.09 14:29
Оценка: +1
Здравствуйте, Lloyd, Вы писали:

G>>Как раз в случаях с Ajax много класов делать не надо. Если передавать на клиента сериализованный в JSON объект, даже класс писать не нужно.

L>Не, нетипизированные методы идут в топку.
На сервере все типизировано, а на клиенте полюбому javascript.
Re[31]: Проблемы организации OR-мапинга
От: Lloyd Россия  
Дата: 19.04.09 14:36
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>Как раз в случаях с Ajax много класов делать не надо. Если передавать на клиента сериализованный в JSON объект, даже класс писать не нужно.

L>>Не, нетипизированные методы идут в топку.
G>На сервере все типизировано, а на клиенте полюбому javascript.

И какой же тип будет у PageMethod-а? А юниттест на это дело как писать?
Re[8]: Проблемы организации OR-мапинга
От: mrTwister Россия  
Дата: 19.04.09 15:02
Оценка:
Здравствуйте, adontz, Вы писали:

A>С каких это пор логин стал Primary Key?


Как сделаешь, так и будет.
лэт ми спик фром май харт
Re[26]: Проблемы организации OR-мапинга
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.04.09 19:34
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>На практике? Не напомнишь хотя бы одну библиотеку доступа к данным, где не было бы доступа к зачению поля по имени?


На моей практике. В ФП кортежи используются весьма часто и то, что при декомпозиции имена назначаешь ты сам проблем не создает.

L>Не поленился и посмотрел, но не нашел ни одного теста, в котором бы демонстрировался доступ к отдельному полю в возвращаемом кортеже.


Ниже же был пример.

VD>>Field1, Field2, ..., Fieldn


L>Ты действительно считаешь, что допустимо иметь такие имена для полей?


В Немерле ты их не увидишь. А в C# других средств нет. Так что это детали реализации которые прийдется знать только тем кто пользуется языками не поддерживающими кортежи.

VD>>
VD>>def custs = linq <# from c in customers
VD>>                    join e on in employees on c.ID == e.CustomerID
VD>>                    select (e.FirstName, e.SurName) #>;
VD>>def html = $<#<ul> ..$(custs; "\n"; (fName, sName) => $"<li>fName, sName</li>") </ul>#>;
VD>>


L>Не, так писать не модно еще со времен коассического ASP. Нынче рулит разделение на model-view-controller.


Ну и? Коллекции customers и employees — это часть модели. Приведенный код — это реализация одного из представлений. Вместо последней строчки можешь подставить любую реализацию.

L>Прятание запросов типа GetCuatomerByFitstName не обсуждается. Речь идет о сокрытии деталей маппинга полей сущностей на поля таблиц базы данных.


А где ты видишь тут дтали отображения? В коде используются некие абстракные коллекции customers и employees. Они скрыват те самые детали отображения. Может они — это ХМЛ.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[27]: Проблемы организации OR-мапинга
От: Lloyd Россия  
Дата: 19.04.09 20:11
Оценка: +1 -1
Здравствуйте, VladD2, Вы писали:

L>>Не поленился и посмотрел, но не нашел ни одного теста, в котором бы демонстрировался доступ к отдельному полю в возвращаемом кортеже.


VD>Ниже же был пример.


Но в тестах его не было.

VD>>>
VD>>>def custs = linq <# from c in customers
VD>>>                    join e on in employees on c.ID == e.CustomerID
VD>>>                    select (e.FirstName, e.SurName) #>;
VD>>>def html = $<#<ul> ..$(custs; "\n"; (fName, sName) => $"<li>fName, sName</li>") </ul>#>;
VD>>>


L>>Не, так писать не модно еще со времен коассического ASP. Нынче рулит разделение на model-view-controller.


VD>Ну и? Коллекции customers и employees — это часть модели. Приведенный код — это реализация одного из представлений. Вместо последней строчки можешь подставить любую реализацию.


Этот код хорошо выглядит только тогда, когда он занимает соседние строчки.
На практике же будет совершенно иначе: запросам не место в представлении, он будут в контроллере.
Когда ты его вынесешь в контроллер, то окажется, что метод контроллера GetEmployees возвращает значения типа IEnumerable<(string * string)>.
А это уже приводит к сл. проблемам:
1. Тот кто будет пользоваться таким классом должен будет знать, что метод возвращает FirstName, LastName.
2. Тот, кто будет править GetEmployees должен будет проверить все места, де потенциально используется код и исправить его.
Прямо-таки классический пример сильной свзяности.

L>>Прятание запросов типа GetCuatomerByFitstName не обсуждается. Речь идет о сокрытии деталей маппинга полей сущностей на поля таблиц базы данных.


VD>А где ты видишь тут дтали отображения? В коде используются некие абстракные коллекции customers и employees. Они скрыват те самые детали отображения. Может они — это ХМЛ.


Раз ты удалил отквоченый текст, то напомню, о чем идет речь:

Например, некоторые параметры не хранятся один-в-один в полях таблицы, а сериализуются в xml-ную колонку. Наличие DAL-а позволяет этот механизм хранения скрыть от бизнеса, что, имхо, очень удобно и позволяет очень просто дополнять поля сущности.

Re[28]: Проблемы организации OR-мапинга
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.04.09 22:07
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Но в тестах его не было.


Тебе нужен пример или поговорить?
оследней строчки можешь подставить любую реализацию.

L>Этот код хорошо выглядит только тогда, когда он занимает соседние строчки.

L>На практике же будет совершенно иначе: запросам не место в представлении, он будут в контроллере.

Это полнейшая чушь! Именно в представлениях им и место. Запросы — это средство доступа к модели. Задача контроллера — преобразовать ввод пользователя в изменение модели. Ни модель, ни представление не должны знать о контроллере. Так что ты просто не верно понимаешь принципы паттерна MVC. Но это уже вопрос другой дискуссии.

На мой взгляд DML-интерфейс встроенный в язык мог бы сделать реализацию контроллера (и за одно бизнес-логики) совершенно прозрачным и относительно простым. Вся требуемая логика могла бы быть реализована на событиях DML-интерфейса. При этом пришлось бы запретить модификацию БД напрямую (в обход DML-интерфейса), но это разумная плата, на мой взгляд.

L>Когда ты его вынесешь в контроллер, то окажется, что метод контроллера GetEmployees возвращает значения типа IEnumerable<(string * string)>.


Не надо делать глупостей и тогда не придется обдумывать как выходить из глупых ситуаций.

L>А это уже приводит к сл. проблемам:

L>1. Тот кто будет пользоваться таким классом должен будет знать, что метод возвращает FirstName, LastName.
L>2. Тот, кто будет править GetEmployees должен будет проверить все места, де потенциально используется код и исправить его.
L>Прямо-таки классический пример сильной свзяности.

Опять двадцать пять! Ты русские слва то понимаешь? Тебе уже сказали, что если требуется вернуть что-то, то достаточно вернуть запрос содержащий нужный список. А в нужном месте выбрать нужные поля. Так что метод у тебя будет возвращать не IEnumerable[string * string], а IQueryble[Employees] или IQueryble[Employees * SomeThinkAlse], а где-то в нужном месте представления запрос возвращенный методом будет уточнен списком требуемых колонок. При этом можно и критерии выборки уточнить. Так как до выполнения запроса он является ни чем иным как собственным описанием в виде AST, то мы вольны изменять его как хотим.

Понятно? Потому что если нет, то я умываю руки. Моих талантов не хватает чтобы донести до тебя казалось бы очевидные вещи.

L>>>Прятание запросов типа GetCuatomerByFitstName не обсуждается. Речь идет о сокрытии деталей маппинга полей сущностей на поля таблиц базы данных.


VD>>А где ты видишь тут дтали отображения? В коде используются некие абстракные коллекции customers и employees. Они скрыват те самые детали отображения. Может они — это ХМЛ.


L>Раз ты удалил отквоченый текст, то напомню, о чем идет речь:

L>

L>Например, некоторые параметры не хранятся один-в-один в полях таблицы, а сериализуются в xml-ную колонку. Наличие DAL-а позволяет этот механизм хранения скрыть от бизнеса, что, имхо, очень удобно и позволяет очень просто дополнять поля сущности.


Ну, и скрывай эти детали. Что тебе мешает, то?

У тебя забавная логика. То ты вспоминаешь о MVC, то вдруг начинаешь скрывать что-то в бинзес-слое. Если у тебя есть модель, то все сокрытие должно делаться в ней. У меодели должен быть интерфейс с короым работают представления и контролер. Интерфейсом модели в нашем случае являются объекты отображения (мапинга), т.е. те самые Employees, Customers и т.п. Если хочешь что-то скрывать, то отображи свой XML на какие-то объекты и опиши как свойство в одном из объектов отображения. Тогда и к этим данным можно убдет обращаться с помощью запросов (прямо в рамках одного запроса к вышележащим данным).
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[29]: Проблемы организации OR-мапинга
От: Lloyd Россия  
Дата: 19.04.09 22:27
Оценка:
Здравствуйте, VladD2, Вы писали:

L>>Этот код хорошо выглядит только тогда, когда он занимает соседние строчки.

L>>На практике же будет совершенно иначе: запросам не место в представлении, он будут в контроллере.

VD>Это полнейшая чушь! Именно в представлениях им и место. Запросы — это средство доступа к модели. Задача контроллера — преобразовать ввод пользователя в изменение модели. Ни модель, ни представление не должны знать о контроллере. Так что ты просто не верно понимаешь принципы паттерна MVC. Но это уже вопрос другой дискуссии.


MVC is often seen in web applications, where the view is the actual HTML or XHTML page, and the controller is the code that gathers dynamic data and generates the content within the HTML or XHTML.

Ты все еще уверен, что я неправильно понимаю MVC?

L>>А это уже приводит к сл. проблемам:

L>>1. Тот кто будет пользоваться таким классом должен будет знать, что метод возвращает FirstName, LastName.
L>>2. Тот, кто будет править GetEmployees должен будет проверить все места, де потенциально используется код и исправить его.
L>>Прямо-таки классический пример сильной свзяности.

VD>Опять двадцать пять! Ты русские слва то понимаешь? Тебе уже сказали, что если требуется вернуть что-то, то достаточно вернуть запрос содержащий нужный список. А в нужном месте выбрать нужные поля. Так что метод у тебя будет возвращать не IEnumerable[string * string], а IQueryble[Employees] или IQueryble[Employees * SomeThinkAlse], а где-то в нужном месте представления запрос возвращенный методом будет уточнен списком требуемых колонок. При этом можно и критерии выборки уточнить. Так как до выполнения запроса он является ни чем иным как собственным описанием в виде AST, то мы вольны изменять его как хотим.


Да все это понятно. Поинт лишь в том, что пихать это в presentation — последнее дело.
UI должен быть туп как пробка и не должен содежать ни методов для формирования чего-либо, ни оперировать запросами.
И мне оч. странно слышать, что кто-то считает иначе.

VD>Понятно? Потому что если нет, то я умываю руки. Моих талантов не хватает чтобы донести до тебя казалось бы очевидные вещи.


Эти очевидные вещи провоцируют на написание плохого кода.

L>>>>Прятание запросов типа GetCuatomerByFitstName не обсуждается. Речь идет о сокрытии деталей маппинга полей сущностей на поля таблиц базы данных.


VD>>>А где ты видишь тут дтали отображения? В коде используются некие абстракные коллекции customers и employees. Они скрыват те самые детали отображения. Может они — это ХМЛ.


L>>Раз ты удалил отквоченый текст, то напомню, о чем идет речь:

L>>

L>>Например, некоторые параметры не хранятся один-в-один в полях таблицы, а сериализуются в xml-ную колонку. Наличие DAL-а позволяет этот механизм хранения скрыть от бизнеса, что, имхо, очень удобно и позволяет очень просто дополнять поля сущности.


VD>Ну, и скрывай эти детали. Что тебе мешает, то?


Отсутствие DAL-а, вестимо. Entity-то отличается от схемы данных.

VD>У тебя забавная логика. То ты вспоминаешь о MVC, то вдруг начинаешь скрывать что-то в бинзес-слое. Если у тебя есть модель, то все сокрытие должно делаться в ней. У меодели должен быть интерфейс с короым работают представления и контролер. Интерфейсом модели в нашем случае являются объекты отображения (мапинга), т.е. те самые Employees, Customers и т.п. Если хочешь что-то скрывать, то отображи свой XML на какие-то объекты и опиши как свойство в одном из объектов отображения. Тогда и к этим данным можно убдет обращаться с помощью запросов (прямо в рамках одного запроса к вышележащим данным).


Подожди. Давай уточним предмет обсуждения.
Обсуждается как это могло бы быть в идеальном случае или все-таки real-world сценарии?
Re[25]: Nemerle & Real Life
От: IT Россия linq2db.com
Дата: 19.04.09 22:32
Оценка:
Здравствуйте, mrTwister, Вы писали:

IT>>Что же касается бизнес логики на TSQL, которую ты здесь привёл, то это одно из двух: либо пережиток старого, либо дурь. Надеюсь первое. Разумного оправдания такой практике сегодня нет.


T>Есть. Называется производительность.


Какая может быть производительность на курсорах? Это во-первых. Во-вторых, если я не ошибаюсь, Том привёл типичный для его проекта код. Как раз то, работу с чем он хотел бы упростить по максимуму. Так что я сомневаюсь, что речь шла об оптимизациях.
Если нам не помогут, то мы тоже никого не пощадим.
Re[30]: Проблемы организации OR-мапинга
От: VladD2 Российская Империя www.nemerle.org
Дата: 19.04.09 23:08
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>

L>MVC is often seen in web applications, where the view is the actual HTML or XHTML page, and the controller is the code that gathers dynamic data and generates the content within the HTML or XHTML.

L>Ты все еще уверен, что я неправильно понимаю MVC?

MVC — это общий архитектурный паттерн и допускает очень вольную трактовку. Но основная суть его — это отделение логики данных от презентационной логики и от логики управления.

Так что чем квотить мелкий кусочик из википедии (не являющейся точным источником данных, кстати) ты прочел бы хотя бы весь раздел. А еще лучше прочитай первоисточник.

Короче понимание MVC — это отдельный вопрос. К сожалению его не понимают очень многие. Не уверен в проценте, но не удивлюсь, если это 70%.

L>Да все это понятно. Поинт лишь в том, что пихать это в presentation — последнее дело.


Что это? Доступ к модели? А куда же его пихать, то?

L>UI должен быть туп как пробка и не должен содежать ни методов для формирования чего-либо, ни оперировать запросами.


Кто сказал такую чушь? Задача представления — отображать данные модели. Какова сложность этого зависит исключительно от двух факторов — сложности представления и сложности модели. Если представление отображает не всю модель целиком, то нужны хорошие инструменты выбрать нужные для отображения данные.

L>И мне оч. странно слышать, что кто-то считает иначе.


Ну, дык чтобы понимать, нужно перейти от оперирования заученными догмами к мыслительному процессу.

VD>>Понятно? Потому что если нет, то я умываю руки. Моих талантов не хватает чтобы донести до тебя казалось бы очевидные вещи.


L>Эти очевидные вещи провоцируют на написание плохого кода.


Ага. Осталось только доказать правоту своей гипотезы. Успехов тебе на этом поприще.

VD>>Ну, и скрывай эти детали. Что тебе мешает, то?


L>Отсутствие DAL-а, вестимо. Entity-то отличается от схемы данных.


В задницу твой DAL. DAL — это костыль для объектно-тексто-скриптовых технологий которым самое время умереть.

L>Подожди. Давай уточним предмет обсуждения.

L>Обсуждается как это могло бы быть в идеальном случае или все-таки real-world сценарии?

Я не отделяю эти понятия. Мне не нравится делать что-то раком и при этом мечтать об идеальном случае.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[31]: Проблемы организации OR-мапинга
От: Lloyd Россия  
Дата: 20.04.09 01:51
Оценка:
Здравствуйте, VladD2, Вы писали:

L>>

L>>MVC is often seen in web applications, where the view is the actual HTML or XHTML page, and the controller is the code that gathers dynamic data and generates the content within the HTML or XHTML.

L>>Ты все еще уверен, что я неправильно понимаю MVC?

VD>MVC — это общий архитектурный паттерн и допускает очень вольную трактовку. Но основная суть его — это отделение логики данных от презентационной логики и от логики управления.


Странно, а пару часов назад было

Ни модель, ни представление не должны знать о контроллере.



VD>Так что чем квотить мелкий кусочик из википедии (не являющейся точным источником данных, кстати) ты прочел бы хотя бы весь раздел. А еще лучше прочитай первоисточник.


Unlike the model, which may be loosely connected to multiple MVC triads, Each view is associated with a unique controller and vice versa. Instance variables in each maintain this tight coupling.



VD>Короче понимание MVC — это отдельный вопрос. К сожалению его не понимают очень многие. Не уверен в проценте, но не удивлюсь, если это 70%.


Твои догадки подтверждаются.

L>>Да все это понятно. Поинт лишь в том, что пихать это в presentation — последнее дело.


VD>Что это? Доступ к модели? А куда же его пихать, то?


В контроллер, другого не остается.

L>>UI должен быть туп как пробка и не должен содежать ни методов для формирования чего-либо, ни оперировать запросами.


VD>Кто сказал такую чушь? Задача представления — отображать данные модели. Какова сложность этого зависит исключительно от двух факторов — сложности представления и сложности модели. Если представление отображает не всю модель целиком, то нужны хорошие инструменты выбрать нужные для отображения данные.


Если подходить формально, то ты прав. А на практеке от кода еще стребуется как минимум тестируемость. Если мы зашиваем часть логики запросов в представление, мы эту возможность теряем.

L>>И мне оч. странно слышать, что кто-то считает иначе.


VD>Ну, дык чтобы понимать, нужно перейти от оперирования заученными догмами к мыслительному процессу.


Лучше от мыслительного процесса переходить к практике.

VD>>>Понятно? Потому что если нет, то я умываю руки. Моих талантов не хватает чтобы донести до тебя казалось бы очевидные вещи.


VD>>>Ну, и скрывай эти детали. Что тебе мешает, то?


L>>Отсутствие DAL-а, вестимо. Entity-то отличается от схемы данных.


VD>В задницу твой DAL. DAL — это костыль для объектно-тексто-скриптовых технологий которым самое время умереть.


Как тогда скрывать детали маппинга? Я кажется, догадываюсь, что ты ответишь. В задницу сокрытие деталей. Оно?

L>>Подожди. Давай уточним предмет обсуждения.

L>>Обсуждается как это могло бы быть в идеальном случае или все-таки real-world сценарии?

VD>Я не отделяю эти понятия. Мне не нравится делать что-то раком


Ну хоть в этом отношении у тебя все нормально.

VD>и при этом мечтать об идеальном случае.


Да чего о нем мечтать, когда идеал уже достугнут. N****** — имя ему
Re[27]: Проблемы организации OR-мапинга
От: Sinclair Россия https://github.com/evilguest/
Дата: 20.04.09 03:28
Оценка:
Здравствуйте, vdimas, Вы писали:
V>Согласно определению разновидностей типизации мы имеем дело с нестрогой + динамической типизацией.
Нестрогость есть, динамики никакой нету. Ты просто не вполне понимаешь, что такое динамика vs статика. Динамикой была бы возможность во время выполнения запроса поменять тип выражения. Увы, в сиквеле всё early bound.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[27]: Проблемы организации OR-мапинга
От: Sinclair Россия https://github.com/evilguest/
Дата: 20.04.09 03:28
Оценка:
Здравствуйте, IT, Вы писали:
IT>Я пока других вариантов не вижу вовсе
А может, всё-таки в конце принимать Expr<Func<Order, Order>> которая должна отображать старый в новый?
У нас же типа всё иммутабл (в лучших традициях жанра), поэтому изменить ничего нельзя.

Это бы работало замечательно, если бы был (автоматически реализованный) Fluent.
То есть как-то так:
(from o in orders where o.OrderDate < xxx select o).Update(o => o.SetDelayed(true));
В предположении, что SetDelayed имеет семантику

public Order SetDelayed(bool delayed)
{
  if (delayed == Delayed)
      return this;

  Order clone = Clone();
    clone._delayed = delayed;
    return clone;
}
public bool Delayed { get { return _delayed; } }

Естественно, при прогоне через SqlProvider этот код никогда не исполняется.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[21]: Проблемы организации OR-мапинга
От: Sinclair Россия https://github.com/evilguest/
Дата: 20.04.09 03:28
Оценка: +1 :))) :))
Здравствуйте, Tom, Вы писали:

IT>>В твоём примере с процедурой? Так там у тебя нет ни DAL, ни BL. Только каша из TSQL.

Tom>Хорошо, приведи пример где не будет каши и где всё будет сделано правильно.
Tom>И если можно покажи там разделение на слои.

Tom>PS:

Tom>Не понял где там каша, вроде был один TSQL запрос
Каша там в том, что непонятно,
1. Откуда было взято решение выделить delayed в отдельное поле. Почему нельзя сделать его вычисляемой колонкой, для которой, к примеру, задано выражение "OrderDate < GetDate()"
2. Что у нас там справа от >? Некая константа? Некоторое выражение — функция от атрибутов ордера, например OrderDate < ActualDeliveryDate?
3. Кто решает, какие еще условия наложить на множество ордеров?

То есть видно, что выше по стеку проделана какая-то большая работа. Но не видно, какая именно.
В жизни правила вычисления факта устарелости ордеров могут быть одни (и могут меняться в зависимости от ответственного менеджера, категории клиента, или фазы луны), способы запоминания этого факта могут быть другими, а набор ордеров для конкретной операции могут быть совершенно третьи.

К сожалению, пока что все системы делятся на две большие группы:
1. Классические клиент-сервера. Характерны большим количеством совершенно шаманских хранимок, которые делают несложные (с точки зрения логики) вещи, но совершенно непостижимы из-за неотъемлемой убогости T-SQL. Никакой композиционной гибкости в них нет, разработчики ходят с серыми лицами и мечтают уехать отсюда куда-нибудь туда, где есть Ajax и Silverlight.
2. Классические ORM. Всё максимально гибко; применены все паттерны Фаулера и несколько своих; в базе — избыточное количество однотипных сгенерированных спроков вида RetrieveXXX; UpdateXXX; и DeleteXXX. C точки зрения СУБД, клиентское приложение (апп-сервер) ведет себя крайне неэффективно: засасывает к себе огромные объемы информации, скармливает обратно килотонны одинаковых запросов типа UpdateXXX.
Производительность "почти устраивает", основные репорты уже переписаны на T-SQL, неосновные ждут своей очереди; разработчики ходят с серыми лицами и мечтают уехать отсюда куда-нибудь туда, где есть Ajax и Silverlight.

3. Есть еще небольшая группа пытающихся бороться с 1 и 2 путем использования динамического T-SQL. Инсталляций мало, система знаменита низкой надежностью, пользователи инстинктивно избегают задавать нетипичные комбинации параметров отчетов. разработчики нервно хихикают при словах "юнит-тестирование", ходят с серыми лицами и мечтают уехать отсюда куда-нибудь туда, где есть Ajax и Silverlight.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[27]: Проблемы организации OR-мапинга
От: Sinclair Россия https://github.com/evilguest/
Дата: 20.04.09 03:28
Оценка: 4 (1)
Здравствуйте, EvilChild, Вы писали:

EC>А почему бы для reflection-based сценариев не расширить этот самый reflection: добавить к

EC>public bool IsAbstract { get; }
EC>public bool IsAnsiClass { get; }
EC>public bool IsArray { get; }
EC>public bool IsAutoClass { get; }
EC>ещё и
EC>public bool IsTuple { get; }
EC>?
Потому, что это не то что нужно. Посмотри, к примеру, на MVC Framework. Там нормальным является скормить в метод в качестве object какую-нибудь new {Category="Beverages", Page=12}. Этакая альтернатива Dictionary<string, object>. А потом внутри это добро исследуется при помощи рефлекшна.
Или там скармливаем IEnumerable<T> с анонимусами в какой-нибудь Grid, а он колонки автоматически по именам мемберов строит.

И всё это накроется в одночасье, как только анонимусы станут туплами. Потому, что "Beverages" превратятся в string Value1, а Page — в int Value2.
Альтернативой могло бы быть наследование анонимуса от тупла. А еще лучше — неявная реализация интерфейса ITuple<T1, T2, T3,...>, чтобы банальный рефлекшн вообще не находил унаследованных ValueN. Но там — свои приколы, связанные с совместимостью по присваиваниям. В том смысле, что мы вроде как ожидаем возможности неявно сконвертировать любой Tuple<string, int> в тип объекта, заданного new {Category="Beverages", Page=12}.
Сценарий конверсии — очень простой. Вот мы берем и получаем откуда-нибудь (например, из линка) некий ICollection<T>, где T — унаследован от Tuple<string, int>.
А в параметр нашего метода приезжает честный Tuple<string, int> (аноним, ессно, приехать не может — он невыносим за пределы метода). И мы его хотим к этой коллекции приклеить. Упс! Налицо жосткое нарушение type safety — некорректный даункаст. Потому что мало ли кто приехал к нам под видом Tuple<string, int>. Может, я там наследника передал.
Возможное решение — при конверсии конструировать новый экземпляр. Но это, опять же, чревато граблями из-за того, что преобразование перестанет сохранять идентичность.

Возможное решение этой проблемы — отказаться от идентичности, т.е. перейти к value-типам. В принципе, желание логичное, т.к. туплы по семантике и должны себя вести как value-типы.
Но тогда мы теряем (по крайней мере в текущем CLR) возможность наследоваться от них. В общем, получается какая-то дупа. Связанная, очевидно, именно с тем, что структурные типы не были включены в рассмотрение при проектировании CLR c самого начала.
Впрочем, я тут не самый умный — в CLR уже работает достаточно злая магия типа неявной реализации большого количества интерфейсов массивами, занятные правила ко/контравариантности для массивов и делегатов (а теперь и для интерфейсов), шаманства с Nullable... Так что, возможно, и придумают злую магию, которая сделает туплы рабочими.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[22]: Проблемы организации OR-мапинга
От: Sinclair Россия https://github.com/evilguest/
Дата: 20.04.09 03:28
Оценка:
Здравствуйте, Lloyd, Вы писали:
L>Я правильно понимаю, что в этом случае под кадую страницу, под каждое использование entity будет обертка, содержащая только нужные поля?
Конечно. Именно за это мы и боролись — чтобы эти обёртки были достаточно дешевы в производстве.

L>В рамках данной ветки этот параметр один — id



L>Ну это скорее исключение, в основном все ограничивается числами и строками.

Да ладно.

L>Ок. Что взамен? По каждый view (не бд, а ui) — пачка presentation классов?

Конечно. Это гораздо лучше, чем one class fits all.

L>xml в описанном сценарии вводился исключительно для того, чтобы избежать частого изменения схемы базы. Если мы под каждое изменение в сущностях будем править вьюхи, то смысл наличия xml теряется.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[20]: Проблемы организации OR-мапинга
От: Sinclair Россия https://github.com/evilguest/
Дата: 20.04.09 03:28
Оценка:
Здравствуйте, adontz, Вы писали:
A>Как схемы БД, так и кода для работы с БД. Да, вот забыл упомянуть, что делать с row level security? Боюсь, если хранимки не генерировать, будет беда.
Делать где? Если в потенциально правильной реализации, то RLS должна реализовываться на функциях высшего порядка.
То есть непосредственно перед материализацией произвольного IQueryable<T> он протаскивается через функцию SecurityCheck().
Ну, а она работает примерно так:
IQueryable<T> SecurityCheck<T>(IQueryable<T> source)
{
  return 
      from s in source where SecurityOk(s) select s;
}

То есть мы, естественно, подразумеваем какие-то более специфичные реализации, типа
IQueryable<T> SecurityCheck<T>(IQueryable<T> source)
  where T: IDACLSecured
{
  return 
      from s in source where s.ID in (from d in Context.DACL where d.UserID == session.CurrentUser.Id select TargetID) select s;
}


Смысл этого — в том, чтобы вовремя накладывать предикаты, а не размазывать эту логику по всем миллионам хранимок копи-пейстом.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[20]: Проблемы организации OR-мапинга
От: Sinclair Россия https://github.com/evilguest/
Дата: 20.04.09 03:28
Оценка: +1
Здравствуйте, adontz, Вы писали:

A>Я уже объяснил — надо отношение многие-ко-многим между двумя типами объёктов прочесть за один раз

Это легко и понятно.
A>и распихать результат по экземплярам обоих типов.
А вот это — непонятно. Зачем тебе эти несчастные экземпляры?

Вот представь, что "многие-ко-многим" — это авиарейсы между городами. Каждый город, естественно, оборудован огромным количеством подробностей. Но вот ты выводишь табличку, к примеру, рейсов конкретной авиакомпании. Зачем тебе "экземпляры" всех городов? Всё, что тебе нужно — это список вида {string Departure, string Destination}. Ну так ты его и получишь!
Если тебе интересно получить граф типа "полное описание города -> список доступных пунктов назначения", то тебе и нужна коллекция структур вида {Сity city, IEnumerable<string> Destinations}. Зачем тебе опять полные экземпляры в правой части?
Хотеть их — вредное занятие. А то, о чем я пишу, тривиально получается в линке. За что мы его и любим.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[28]: Проблемы организации OR-мапинга
От: Sinclair Россия https://github.com/evilguest/
Дата: 20.04.09 03:28
Оценка:
Здравствуйте, adontz, Вы писали:
A>Влад, мы не реплицируем БД. в данном случае репликация — это костыль для твоей системы неспособной к локальному кешированию.
Это как раз ОRM-системы неспособны к локальному кэшированию. Там кэш может быть исключительно глобальный, иначе ты мгновенно напорешься на рассогласование.

А в linq-подходе, о котором говорит Влад, запросто можно (если нужно) кэшировать конкретный результат конкретного запроса.

На практике, к примеру, работа с почтой через OWA жрет в разы меньше трафика, чем честная синхронизация Outlook. А это — именно то, о чем ты говоришь. Синхронизация притаскивает на клиента полную реплику базы, и она обязана постоянно бегать и рефрешить все изменившиеся объекты — а то вдруг война (пользователь ткнул в объект), а я без каски (он устарел).
OWA кэширует на клиенте очень-очень мало, но это ей не страшно — всё равно показывается только то, что запросил клиент.

Причем по этому пути можно заходить достаточно далеко — если сделать протокол взаимодействия клиента и сервера более умным, чем плоский SQL/TDS. К примеру, для некоторых (только тех, которые нужны) видов запросов сервер может обучиться вычислять LastModifiedDate и сравнивать ее с датой, переданной клиентом в запросе. Ну, а дальше — традиционное 304 либо 200, смотря что нашлось. Это я не говорю про RFC3229, который позволяет обмениваться только "дельтами".
И при должном развитии Linq в широком смысле слова (как интеграции запросов в язык) это всё можно делать в достаточно обобщенном виде. Как только мы включаем реляционную алгебру, мы опять получаем возможность прицепить "delta-predicate" к любому запросу, который содержит LastModifiedDate. Это не будет затенять основную бизнес-логику, потому что будет описано в совершенно ортогональном ей месте.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.