Re[6]: Работа с ORM
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 26.07.11 15:52
Оценка: +1
Здравствуйте, Gengzu, Вы писали:

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


Тогда много что не подойдет. Если делать веб-сервисы, то сам способ взаимодейтсвия с сервером сильно изменится. Придется реально каждый запрос к серверу считать, не то что запросы к БД.

Кстати для выставления данных через http есть Odata (wcf data services), которые поддерживают IQueryable.
Re[18]: Работа с ORM
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 26.07.11 16:06
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>
G>var result = _users.Where(u => u.IsActive)
G>

G>А result твой какого типа?

тьфу, такой код:

var result = _users.Where(spec.IsSatisfiedBy());


Вот какого типа тут result?
Re[18]: Работа с ORM
От: Gengzu  
Дата: 26.07.11 19:43
Оценка:
G>А почему бы не

G>
G>var result = _users.Where(u => u.IsActive)
G>

G>?

G>Или еще лучше

G>
G>var result = _users.Active()
G>

G>где
G>
G>public static IQueryable<T> Active(this IQueryable<T> seq) where T:IActivateable, class
G>{
G>    return seq.Where(e => e.IsActive);
G>}

G>public interface IActivateable
G>{
G>    bool IsActive { get; set; }
G>}

G>class User: IActivateable //,..
G>{
G>    //...
G>}
G>


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


G>>я её могу покрыть тестами, что и делаю. это условие, часть бизнес логики. логично что на это должны быть тесты. и они есть.

G>Не понятно? Ты сделал что-то, покрыл тестами, хотя без этого "что-то" то же самое проверяет компилятор.

Компилятор тут не причем. Этот кусок бизнес логики. на него есть тест.
более того, спецификации могут быть использованы для валидации бизнес объектов.

G>А result твой какого типа?


это кусок из предпологаемого тестового метода, и тип возвращемых данных в данном случае совершенно не имеет значения.
Re[17]: Работа с ORM
От: Ziaw Россия  
Дата: 27.07.11 01:13
Оценка:
Здравствуйте, Gengzu, Вы писали:

Z>>Машушвать! Продемонстрируй ка тест на AgeLessThan


G>а в чем проблема?


G> var spec = new ActiveUserSpecification();


G> var result = _users.Where(spec.IsSatisfiedBy());


1) Без ассерта это не тест.
2) даже если добавить ассерт, это будет не юнит-тест

О каком облегчении тестирования идет речь совершенно не ясно.
Re[18]: Работа с ORM
От: Ziaw Россия  
Дата: 27.07.11 07:15
Оценка:
Здравствуйте, gandjustas, Вы писали:

Z>>Протаскивается только предикат и протаскивается в одну сторону. Против этого я ничего не имею. Все протаскивание выглядит так PL->BL->DAL.

G>Покажи как в коде будет выглядеть то что ты предлагаешь. Особенно интересуют проекции.

Я вообще за простоту и передаю сессию везде где она требуется. Если же физически нет доступа, или очень хочется архитектурно отвязать PL от ORM можно придумать такой вариант:
var pairs = ExecuteQuery<Entity1, Entity2>((e1src, e2src) =>
{
  return from e1 in e1src
  from e2 in e2src
  where e1.Entity2Id = e2.Id
  select new { e1.Id, e2.Name }
})

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

Z>>Обертку ORM для облегчения тестирования, конечно, сделать можно, только зачем называть ее Repository и делать для каждой сущности?

G>А зачем для каждой сущности? Я примерно вот так делаю.

Все равно для каждой сущности получается свой тип. Generics или кодогенерация, не суть важно. Так для какой цели оно делается? Только для облегчения тестирования? Цель вобщем-то понятная, только это не является основной целью классического паттерна репозитарий.
Re[19]: Работа с ORM
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.07.11 09:52
Оценка: +1
Здравствуйте, Gengzu, Вы писали:


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

G>А так ничего. всё хорошо.
Идеологические аргументы самые бесполезные. Ибо важны метрики, например если что-то дает меньше кода и его легче поддерживать, то срать я хотел на идеологию, которая что-то запрещает. И вам того же желаю.


G>>>я её могу покрыть тестами, что и делаю. это условие, часть бизнес логики. логично что на это должны быть тесты. и они есть.

G>>Не понятно? Ты сделал что-то, покрыл тестами, хотя без этого "что-то" то же самое проверяет компилятор.

G>Компилятор тут не причем. Этот кусок бизнес логики. на него есть тест.

Если что-то проевяется компилятором, то этому не нужны тесты. Тесты — костыль для того что не проверяет компилятор и другие инструменты статического анализа.

G>более того, спецификации могут быть использованы для валидации бизнес объектов.

Так же как обычные предикаты. Никто ведь не мешает сохранить предикат в переменную и подсовывать его через IoC.

G>>А result твой какого типа?

G>это кусок из предпологаемого тестового метода, и тип возвращемых данных в данном случае совершенно не имеет значения.
Раз уж ушел от ответа, то видимо IQueryable.
А в реальном коде как оно выглядит? Интересно посмотреть на control flow между классами в реальном случае.
Re[19]: Работа с ORM
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.07.11 09:58
Оценка:
Здравствуйте, Ziaw, Вы писали:

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


Z>>>Протаскивается только предикат и протаскивается в одну сторону. Против этого я ничего не имею. Все протаскивание выглядит так PL->BL->DAL.

G>>Покажи как в коде будет выглядеть то что ты предлагаешь. Особенно интересуют проекции.

Z>Я вообще за простоту и передаю сессию везде где она требуется. Если же физически нет доступа, или очень хочется архитектурно отвязать PL от ORM можно придумать такой вариант:

Z>
Z>var pairs = ExecuteQuery<Entity1, Entity2>((e1src, e2src) =>
Z>{
Z>  return from e1 in e1src
Z>  from e2 in e2src
Z>  where e1.Entity2Id = e2.Id
Z>  select new { e1.Id, e2.Name }
Z>})
Z>

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

Чем это лучше обычного вызова Select? ты ведь все равно пишешь Linq со всеми вытекающими последствиями, о которых говорят другие ораторы.

Z>>>Обертку ORM для облегчения тестирования, конечно, сделать можно, только зачем называть ее Repository и делать для каждой сущности?

G>>А зачем для каждой сущности? Я примерно вот так делаю.

Z>Все равно для каждой сущности получается свой тип. Generics или кодогенерация, не суть важно. Так для какой цели оно делается? Только для облегчения тестирования?

Да, именно так. Причем в последних версиях EF и такое писать не нужно, есть IObjectSet.

Z>Цель вобщем-то понятная, только это не является основной целью классического паттерна репозитарий.

"Классический паттерн репозитарий" был придуман в 90-х годах прошлого века. Важно за всеми sequence и другими диаграммами понимать суть. А суть заключается в том что репозиторй должен отдавать данные в зависимости от некоторого query object. Чтобы репозиторий при желании можно было подменить. В данном случае что-то типа IObjectSet более чем достаточно.
Re[20]: Работа с ORM
От: Ziaw Россия  
Дата: 27.07.11 10:35
Оценка:
Здравствуйте, gandjustas, Вы писали:

Z>>Я вообще за простоту и передаю сессию везде где она требуется. Если же физически нет доступа, или очень хочется архитектурно отвязать PL от ORM можно придумать такой вариант:

Z>>
Z>>var pairs = ExecuteQuery<Entity1, Entity2>((e1src, e2src) =>
Z>>{
Z>>  return from e1 in e1src
Z>>  from e2 in e2src
Z>>  where e1.Entity2Id = e2.Id
Z>>  select new { e1.Id, e2.Name }
Z>>})
Z>>

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

G>Чем это лучше обычного вызова Select? ты ведь все равно пишешь Linq со всеми вытекающими последствиями, о которых говорят другие ораторы.


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

G>А суть заключается в том что репозиторй должен отдавать данные в зависимости от некоторого query object. Чтобы репозиторий при желании можно было подменить.


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

Суть его по Фаулеру:

build another layer of abstraction over the mapping layer where query construction code is concentrated.

Убери эту суть, останется голый адаптер для уменьшения связанности и облегчения тестирования. Никак не связанный с БД или еще чем-то.

Несмотря на устаревание, неокрепшие умы начитавшись Фаулера пытаются заюзать сразу все паттерны из книжки в надежде на то, что программистам в хиторосплетении этой архитектуры негде будет делать ошибки.
Re[21]: Работа с ORM
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 27.07.11 13:55
Оценка:
Здравствуйте, Ziaw, Вы писали:

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


Z>>>Я вообще за простоту и передаю сессию везде где она требуется. Если же физически нет доступа, или очень хочется архитектурно отвязать PL от ORM можно придумать такой вариант:

Z>>>
Z>>>var pairs = ExecuteQuery<Entity1, Entity2>((e1src, e2src) =>
Z>>>{
Z>>>  return from e1 in e1src
Z>>>  from e2 in e2src
Z>>>  where e1.Entity2Id = e2.Id
Z>>>  select new { e1.Id, e2.Name }
Z>>>})
Z>>>

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

G>>Чем это лучше обычного вызова Select? ты ведь все равно пишешь Linq со всеми вытекающими последствиями, о которых говорят другие ораторы.


Z>Ответ на вопрос я дал. На всякий случай выделил. Последствия других ораторов на фоне предлагаемых альтернатив безмерно доставляют.


Насколько я понимаю доводы противников IQueryable заключаются в том что для IQueryable можно написать любой запрос в том числе заведомо неэффективный и\или противоречащий БЛ. Получать или не получать session или любой другой объект "соединения с бд" тут разницы не имеет.

G>>А суть заключается в том что репозиторй должен отдавать данные в зависимости от некоторого query object. Чтобы репозиторий при желании можно было подменить.


Z>Ты делаешь обычный адаптер. Нормальное решение против которого я ничего не имею. А то, что репозитарий давно морально устарел, я и пытаюсь тут объяснить.

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

Z>Суть его по Фаулеру:

Z>

Z>build another layer of abstraction over the mapping layer where query construction code is concentrated.

Z>Убери эту суть, останется голый адаптер для уменьшения связанности и облегчения тестирования. Никак не связанный с БД или еще чем-то.
Я бы все таки обратил внимание на то что он пишет в PoEAA. Там нету модного нынче популяризторства DDD и других аббривеатур.
Re[22]: Работа с ORM
От: Ziaw Россия  
Дата: 27.07.11 15:55
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Насколько я понимаю доводы противников IQueryable заключаются в том что для IQueryable можно написать любой запрос в том числе заведомо неэффективный и\или противоречащий БЛ. Получать или не получать session или любой другой объект "соединения с бд" тут разницы не имеет.


Другие ораторы говорят странные вещи. Я тебе отвечал на вопрос, как можно избавиться от протаскивания контекста через все слои, особенно если они вдруг превращаются в звенья. С "другими ораторами" я уже не знаю о чем говорить. Ты тоже считаешь, что проблему неэффективных запросов можно решить заменив expression tree на свое самопальное query tree? Я так считаю, что чем проще программисту строить запрос, чем прозрачнее он видит SQL за ним, тем запросы будут эффективнее. Самые эффективные запросы будут если программист их будет писать напрямую в коде, но там возникнут другие серьезные проблемы. И наоборот, чем больше абстракций навешать между базой и бизнес логикой, тем менее эффективно будет использоваться база.

G>Я бы все таки обратил внимание на то что он пишет в PoEAA. Там нету модного нынче популяризторства DDD и других аббривеатур.


Вот тут должна быть цитата из того, что он пишет в PoEAA, но ее почему-то нет. Читал я ее очень давно и представление сейчас имею довольно общее. То, что репозитарий там несколько больше тривиального адаптера к ORM у меня особых сомнений нет, но чем черт не шутит. Тем не менее перечитывать не буду, врядли уже вынесу что-то новое.
Re[23]: Работа с ORM
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 28.07.11 09:38
Оценка:
Здравствуйте, Ziaw, Вы писали:

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


G>>Насколько я понимаю доводы противников IQueryable заключаются в том что для IQueryable можно написать любой запрос в том числе заведомо неэффективный и\или противоречащий БЛ. Получать или не получать session или любой другой объект "соединения с бд" тут разницы не имеет.


Z>Другие ораторы говорят странные вещи. Я тебе отвечал на вопрос, как можно избавиться от протаскивания контекста через все слои, особенно если они вдруг превращаются в звенья.

Дык ты не избавился, ты только скрыл его в методе, но точно так же пишешь expression tree, в который передаешь параметры через замыкания.

Z>Ты тоже считаешь, что проблему неэффективных запросов можно решить заменив expression tree на свое самопальное query tree?

Я вообще не читают проблемой использовать IQueryable где нужно.

G>>Я бы все таки обратил внимание на то что он пишет в PoEAA. Там нету модного нынче популяризторства DDD и других аббривеатур.

Z>Вот тут должна быть цитата из того, что он пишет в PoEAA, но ее почему-то нет. Читал я ее очень давно и представление сейчас имею довольно общее. То, что репозитарий там несколько больше тривиального адаптера к ORM у меня особых сомнений нет, но чем черт не шутит. Тем не менее перечитывать не буду, врядли уже вынесу что-то новое.

У меня под рукой к сожалению нет книжки.
Re[24]: Работа с ORM
От: Ziaw Россия  
Дата: 28.07.11 16:58
Оценка:
Здравствуйте, gandjustas, Вы писали:

Z>>Другие ораторы говорят странные вещи. Я тебе отвечал на вопрос, как можно избавиться от протаскивания контекста через все слои, особенно если они вдруг превращаются в звенья.

G>Дык ты не избавился, ты только скрыл его в методе, но точно так же пишешь expression tree, в который передаешь параметры через замыкания.

Да нет же, фича как раз в том, что контекст соединения тут не нужен. Сформированное expression tree можно передать за границу процесса.

G>Я вообще не читают проблемой использовать IQueryable где нужно.


Re[25]: Работа с ORM
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 29.07.11 15:30
Оценка:
Здравствуйте, Ziaw, Вы писали:

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


Z>>>Другие ораторы говорят странные вещи. Я тебе отвечал на вопрос, как можно избавиться от протаскивания контекста через все слои, особенно если они вдруг превращаются в звенья.

G>>Дык ты не избавился, ты только скрыл его в методе, но точно так же пишешь expression tree, в который передаешь параметры через замыкания.

Z>Да нет же, фича как раз в том, что контекст соединения тут не нужен. Сформированное expression tree можно передать за границу процесса.


В общем случае нельзя, а в частном случае пофиг есть контекст или нет.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.