2014-01-22 1 views
3

Я довольно новичок в NHibernate, и я пытаюсь создать файл сопоставления для расширения проекта модели данных. Конкретная таблица, которую я собираю, называется AttributeDef в следующем изображении, столбец ControlType на самом деле связан с поиском в таблице Code (да, я знаю - должно быть ограничение FK, но такая вещь довольно распространена в этом проекте поэтому, пожалуйста, игнорируйте очевидных воинов и сосредоточьтесь на вопросе). В большинстве случаев таблицы, которые ссылаются на код, также имеют столбец, который содержит идентификатор из таблицы CodeSet, поскольку ключ в коде является почти неизбежным составным ключом, но не в этом случае, предположительно, потому что автор оригинала «Эй, они все из того же кода, так в чем смысл? ».Жесткие кодированные значения в файлах Nhibernate Mapping

Table structure relating to problem

Теперь если есть столбец в AttributeDef который содержит значение Codeset того отображения не было бы большим проблема. Отображение для кода объекта выглядит следующим образом:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
       assembly="Activus.DataModel" namespace="Activus.DataModel"> 

    <class name="Code" table="Code" mutable="false"> 

    <composite-id name="CompositeCodeId" class="CompositeCodeId"> 
     <key-property name="CodeId" column="CodeId"/> 
     <key-property name="CodeSet" column="CodeSet"/> 
    </composite-id> 

    <property name="Description" column="Description" type="string" length="100" not-null="true"/> 
    <property name="ExternalRef" column ="ExternalRef" type ="string" length ="256" not-null ="true"/> 
    <property name="InternalRef" column ="InternalRef" type ="string" not-null ="false"/> 
    <many-to-one name="CodeSet" class="CodeSet" column="CodeSet" not-null="true" insert="false" update="false"/> 

    </class> 

</hibernate-mapping> 

Поэтому если есть столбец в AttributeDef для значения Codeset (умозрительно называется FormControlCodeSet в этом примере), то в моем файле отображения AttributeDef Я хотел бы включить

<many-to-one name="ControlType" class="Code" not-null="false"> 
    <column name="ControlType" /> 
    <column name="FormControlCodeSet" /> 
</many-to-one> 

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

Так же, как это ужасно, ужасно размышлять, можно ли заменить линию

<column name="FormControlCodeSet" /> 

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

ответ

2

При работе с NHiberante вам не нужно требовать шепота. Поскольку сотрудничество с устаревшим DB (т. Е. Фиксированная схема БД) довольно стандартно, NHibernate поддерживает множество различных настроек.

Одним из них является пара (замещающих) настройки: "column" против "formula". Первый занимает столбец , равно, второй может сделать независимо от того, нам нужно. Возьмите столбцы, столбцы, передайте константу. Итак:

<many-to-one name="ControlType" class="Code" not-null="false"> 
    <column name="ControlType" /> 
    <!-- let's replace this --> 
    <!--<column name="FormControlCodeSet" />--> 

    <!-- 1) with a constant number 123--> 
    <formula>123</formula> 
    <!-- 2) with a constant string 'constantString' --> 
    <formula>'constantString'</formula> 
</many-to-one> 

Не уверен, что если константа FormControlCodeSet должна быть int или string, но, как показано выше, либо вариант возможен.

+0

Perfect - спасибо! Я искал такие элементы, как «константа», даже не считал «формулой». Теперь мне просто нужно убедить своего босса, насколько бедно, что нужно полагаться на такие вещи и что нам действительно нужно улучшить «реляционную» часть! –

+0

Отлично, если это так или иначе помогло;) Наслаждайтесь NHibernate –

+1

Это заставило меня думать, что я могу избежать использования константы, и теперь у меня она работает с использованием запроса.Потребовалось некоторое время, поскольку я не мог найти хорошего объяснения, но для тех, кто следует, ваш произвольный SQL-запрос нуждается в псевдониме, или NHibernate предполагает, что столбцы принадлежат родительской таблице для карты и будут их псевдонимами. Я также видел много людей, говорящих, что вам нужно использовать двойные кавычки вокруг него, что не так. Поэтому я закончил с (SELECT CodeSet.CodeSet FROM CodeSet WHERE CodeSet.ViewName = 'FormControl'), который отлично работает. –