ORM для использования с базами данных с полужестким дизайном схемы - PullRequest
1 голос
/ 27 января 2012

Мне нравится «микро» подход Dapper, Massive, PetaPoco и т. Д., И мне нравится контролировать SQL, который мы отправляем в базу данных, в большинстве случаев это относительно просто.Мне также нравится работать с POCO, однако при работе с довольно гибким дизайном схемы вы часто сталкиваетесь с проблемами:)

Допустим, у нас есть объект Person, который ВСЕГДА имеет следующие свойства.

  • Id
  • Имя
  • Электронная почта
  • Телефон

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

  • SpecialPhoneNumber
  • VeryCustomValue

Я бы очень хотел POCO с общими свойствами, которые, как мы знаем, всегда будут там.Но есть другой доступный в коллекции ключ / значение.

Каков будет лучший подход?И поддерживает ли это какой-либо из упомянутых «мирко-ормов»?Я просмотрел их все, но не нашел никаких признаков того, что они это делают, но, возможно, я что-то упустил.

Можно ли сделать это напрямую с помощью SqlDataReader?или производительность чтения сотен строк будет плохой при использовании отражения для создания объектов?Кажется, что все упомянутые ормы работают довольно хорошо, и я предполагаю, что под ними используется DataReader.

Надеюсь, вы можете помочь:)

РЕДАКТИРОВАТЬ: Я должен упомянуть, что у нас нет контроля над приложениемархитектура.Это ERP-решение, которое позволяет индивидуальному клиенту настроить свое приложение и базовую базу данных.Добавление полей в приложение добавляет столбцы в базу данных.Плохо мне!за то, что я не прояснил это в первую очередь

Ответы [ 5 ]

1 голос
/ 28 января 2012

Massive может поддерживать это, поскольку оно материализует данные в ExpandoObject 's:

Секретным соусом является ExpandoObject. Все, что входит и все, что выходит из Massive - это Expando, что позволяет вам делать с ней все что захочешь. По сути, ExpandoObject является просто IDictionary

ExpandoObject реализует IDictionary<string, Object> и IEnumerable<KeyValuePair<string, Object>>, так что вы можете перечислять и проверять элементы любым способом, который вам необходим.

По умолчанию Massive отправляет запрос SELECT *, поэтому ExpandoObject будет содержать все поля в таблице, даже те, о которых вы не знаете.

Вы можете получить текущий код Massive от Github .

Dapper также может выделять динамические объекты, но в отличие от Massive он может только выбирать данные и не может вставлять, обновлять или удалять их. РЕДАКТИРОВАТЬ: Просмотр документов Dapper, кажется, что он может выполнять изменения, так как он может выполнить любой sql. имеется более свежая информация о выполнении вставок с помощью Dapper .

0 голосов
/ 28 января 2012

Вы можете взглянуть на динамическое отображение nHibernate.

http://ayende.com/blog/3942/nhibernate-mapping-dynamic-component

Позволяет извлекать такие расширенные свойства в общий Directory<string,object>. Таким образом, у вас есть ваши классы с такими общими пакетами (словарями) и динамически расширяете отображение XML.

nHibernate сделает все остальное за вас.

0 голосов
/ 27 января 2012

Используйте таблицу для наследования типов или таблицу расширений в своем проекте, чтобы разрешить добавление данных на объект.

0 голосов
/ 27 января 2012

MyBatis.NET (ранее iBatis.NET) - это инструмент для отображения данных, у которого есть особенность, которую я считаю действительно полезной.Если вы никогда не слышали об этом, это инструмент ORM, который позволяет вам писать SQL, создавать объекты домена и использовать XML для сопоставления столбцов базы данных со свойствами объекта домена.

Oneиз этих отображений результатов может выглядеть следующим образом:

<resultMap id="Contact" class="Contact" >
    <result property="ContactId" column="ContactId" />
    <result property="FirstName" column="FirstName" />
    <result property="MiddleInitial" column="MiddleInitial" />
    <result property="LastName" column="LastName" />
</resultMap>

Там у вас есть идентификатор для результата, псевдоним класса (который сопоставляется с Namespace.Folder.Contact, например), и список столбцов длясопоставления свойств.

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

<resultMap id="Person" class="Person" >
    <result property="Id" column="Id" />
    <result property="Name" column="Name" />
    <result property="Email" column="Email" />
    <result property="Phone" column="Phone" />
</resultMap>

А для вашей другой ситуации:

<resultMap id="PersonExtended" extends="Person" class="Person">
    <!-- inherits all the "Person" result map properties -->
    <result property="SpecialPhoneNumber" column="SpecialPhoneNumber" />
    <result property="VeryCustomValue" column="VeryCustomValue" />
</resultMap>

И тогда у вас будет два отдельных запроса, один из которых выбирает только основную информацию и картык карте результатов "Person" и другому запросу, который сопоставляется с картой результатов "PersonExtended", которая включает в себя больше столбцов.

Существует также поддержка выбора в словарях и избежания выбора N + 1.И просто заметьте: я никак не связан с проектом MyBatis, я просто нашел его очень гибким и довольно надежным средством отображения данных.Я использую его для всех своих проектов в основном потому, что написал инструмент, который может генерировать весь слой доступа к данным, просто указав его на базу данных.

Настройка - это немного PITA, но, возможно, он может работать длявы!

0 голосов
/ 27 января 2012

Id Name Email Phone Но в некоторых случаях могут быть дополнительные свойства, такие как SpecialPhoneNumber VeryCustomValue

Отправить архитектора обратно в школу программистов 101. Ошибка проектирования - оба свойства Phone, SpecialPhoneNumber НЕ являются свойствамиof Person (который, в любом случае, не Person, а "Entity", поскольку он также может быть юридическим лицом).

Это список "точек контакта" или что-то в этом роде.

Сказанное, контейнеры свойствтакже может быть продемонстрировано в ORM, с плохой производительностью, но, эй, так работают базы данных sql.Плохая производительность для полей свойств.

...