Подтвердить что ты не робот

.NET ORM нужны виртуальные и не могут иметь дело с запечатанными?

Я только начинаю с .NET ORM, до того момента, когда я даже не решил между Entity Framework и NHibernate. Но в обоих случаях у меня возникает проблема в том, что они, похоже, хотят, чтобы я скомпрометировал целостность моей модели домена различными способами, особенно в тонких точках дизайна объектов С#. Это один из нескольких вопросов по этому вопросу.


Существует причина virtual не является значением по умолчанию для методов в С#. Объекты моей модели домена не готовы сделать promises о поведении подклассов, за исключением особых случаев, когда я отмечаю их как таковые. Другими словами, для очень немногих методов в моих объектах домена целесообразно добавить крючок для неопределенной новой функциональности.

Но NHibernate хочет, чтобы я сделал все virtual, и Entity Framework хочет, чтобы я сделал все ссылки на сущности virtual. Я понимаю, зачем им это нужно (для создания прокси-объектов), и я понимаю, что это на самом деле законное использование наследования и virtual --- они фактически подключаются к моим свойствам, чтобы добавить новые функции. Но это на меня нападает, что я должен аннотировать классы моей модели домена с чем-то, что полностью связано с настойчивостью, и вовсе не выражает их фактический контракт с исполнителями и потребителями.

В качестве более мелкой проблемы, которая, как я понимаю, я, вероятно, ничего не могу сделать, часто выразительно комментировать мои классы с помощью sealed по всем обычным причинам. Это немного меньше решетки, хотя, поскольку исключение аннотации из моих объектов домена для целей настойчивости кажется менее плохим, чем добавление одного.


Неудивительно, что после нескольких лет чтения таких книг, как Effective С# или блоги, таких как Eric Lippert, которые дают отличный совет по разработке выразительных и пуленепробиваемых объектов С#, необходимость использования ORM заставляет меня бросить большую часть этих знаний из окна. Я надеюсь, что кто-то здесь может указать, где я ошибаюсь, либо в своем понимании своих возможностей, либо в моих мыслях о моделировании домена и роли ORM.

4b9b3361

Ответ 1

Это не только .NET ORM - те же ограничения применимы и к ORM-устройствам Java.

Хотя в Java все виртуально, если вы явно не объявляете иначе, поэтому необходимость удовлетворить ORM очень похожа на ситуацию, которую вы находите с помощью sealed:

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

То, что это сводится к такому: Персистирование Незнание - это стоящая цель, но это не тот, который может быть достигнут на 100%, если вы не захотите также игнорировать второстепенные детали, такие как загрузка и производительность памяти.

Если загрузка и производительность памяти не имеют значения, прекратите использование прокси и потребуйте, чтобы все ваши объекты были полностью заполнены, как только они были гидратированы - NHibernate может сделать это через конфигурацию. Побочным эффектом будет то, что все связанные объекты будут загружены за один раз, поэтому вы получите большую часть загруженной в память базы данных. Приложению понадобится много памяти и потребуется много времени для запуска - но это сработает.

Persistance - это нечеткая абстракция - в то время как вы можете скрыть большую часть занавеса, всегда будут элементы, которые просачиваются в другие области ваше приложение.

Ответ 2

Как мягко это сделать... Извините, я не могу. Отойдите над ним.

Я согласен с вами на 100%, но использование фреймворков всегда означает компромисс. Не хотите идти на компромисс? Постройте его самостоятельно. Это действительно все, что есть.

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

Но это действительно много работы. И за небольшое количество чистоты, которое вы бросаете, вы сэкономите много усилий.

Ответ 3

Существует виртуальная причина. по умолчанию для методов в С# [ссылка на интервью с Андерсом Хейлсбергом].

Хейлсберг фактически говорит о разработке API-интерфейсов. Он ничего не говорит о приложениях Business of Business. Поэтому его правила меньше применяются в приложениях больших объектов. Поскольку вы используете O/RM, вы, вероятно, пишете приложение LOB.

часто это выразительно, чтобы комментировать мои классы с запечатанными для всех обычных причины [ссылка на блог Эрика Липперта].

Вы ссылаетесь на одну из статей Эрика Липперта, которая написала эту статью в контексте своей работы в команде компилятора С#. Общее Руководство по разработке каркаса фактически содержит противоположную рекомендацию:

НЕ заклейте классы, не имея это повод для этого. [пункт 6.3]

Другими словами, то, что говорит Эрик Липперт, не является общим правилом.

Лично, когда я пишу LOB-приложения, я на самом деле запечатываю свои классы и пишу не виртуальные методы, когда это возможно. Однако это не имеет ничего общего с изменением внесения изменений в более поздний выпуск, поскольку это почти исключительно проблема проектирования структуры.

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

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

Очевидно, вам также нужна эта гибкость, и поскольку вы пишете приложение LOB, просто будьте практичны и помните, что:

В любом случае они больше похожи на рекомендации

Ответ 4

Я понимаю разочарование. Одна из возможностей заключается в использовании аспектно-ориентированного программирования (AOP), такого как PostSharp, для отметки всех свойств virtual во время компиляции. Недостатком этого является накладные расходы, связанные с процессом PS ткачества, который увеличивает общее время компиляции.

Просто для удовольствия: сейчас я работаю над исследовательским проектом, который является предварительным ORM на основе АОП (предварительно называется Trinity). Цель состоит в том, чтобы иметь полную емкость для ленивой загрузки без необходимости вводить прокси (или ключевое слово virtual). Самое главное, это позволяет независимой модели сохранять постоянство (не наследование, объекты POCO и т.д.), Но при этом предоставляют те же возможности, что и NHibernate.

AOP все еще очень много на уровне исследований, но это был интересный проект для работы. Я попытаюсь открыть исходный код проекта, как только бумага будет готова.

Ответ 5

В NHibernate не нужно делать все virtual. Если вы не используете "динамические прокси", вам не нужно делать все виртуальным, и вы можете сделать свои классы закрытыми.

NHibernate по умолчанию использует динамические прокси. Поступая таким образом, NHibernate создает класс, который наследуется от вашего класса, чтобы он мог убедиться, что при извлечении экземпляра заполняется только идентификатор этого класса. Свойства класса будут загружаться только при первом обращении к одному из свойств.

Вы можете отключить динамически-прокси-функциональность, указав lazy=false на свой класс-сопоставление:

<class name="MyEntity" table="SomeTable" lazy="false">
</class>