Моделирование один для обнуления или отношения (Z кардинальность)

Я изо всех сил пытаюсь найти лучший способ к модели 1: 0,1 отношения ("может иметь один" или, "имеют самое большее один"). Я полагаю, что это называют кардинальностью Z.

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

Я хотел бы, чтобы мой открытый интерфейс был:

Widget
    WidgetTest { get; set; }

WidgetTest
    Widget { get; }

Модель 1: Виджет имеет свойство WidgetTest, и в базе данных таблица Widget имеет исключительно ограниченный внешний ключ к WidgetTest. Мой DBA утверждает, что это позволило бы записи WidgetTest существовать без Виджета.

WidgetTable
    WidgetTestId (FK, UQ)

Модель 2: Виджет имеет частную коллекцию WidgetTest и осуществляет 0,1 отношения путем добавления или удаления отдельного объекта из набора, которым управляет общедоступное свойство WidgetTest. Модели базы данных это как 1:m с WidgetTest, имеющим исключительно ограниченный внешний ключ к Виджету. Я утверждаю, что это означает принимать модель для установки схеме базы данных (т.е. больше работы для меня).

WidgetTestTable
    WidgetId (FK, UQ)

Какая модель лучше? Которого легче достигнуть с NHibernate? Или есть ли третий путь?

Редактирование... Вот то, с чем я закончил:

public class Widget
{
    // This is mapped in NH using a access strategy
    private IList<WidgetTest> _widgetTests = new List<WidgetTest>(1);

    public WidgetTest
    {
        get { return _widgetTests.FirstOrDefault(); }
        set
        {
            _widgetTests.Clear();
            if (value != null)
            {
                _widgetTests.Add(value);
            }
         }
     }
}
8
задан Jamie Ide 6 February 2010 в 15:46
поделиться

2 ответа

Мой подход заключался в моделировании отношения «один ко многим» в сопоставлениях, но при ограничении «многих» одним элементом. Это позволяет использовать необязательный параметр «один к одному», а также гарантирует, что ваш экземпляр WidgetTest сохраняется при сохранении виджета. Например:

public class Widget
{
    /// <summary>
    /// This property is ignored by the NHibernate mappings.
    /// </summary>
    public virtual WidgetTest WidgetTest { get; set; }

    /// <summary>
    /// For easier persistence with NHibernate, this property repackages the
    /// WidgetTest property as a list containing a single item. If an
    /// attempt is made to set this property to a list containing more than
    /// one item, an exception will be thrown. But why bother? Just use the
    /// WidgetTest property.
    /// </summary>
    public virtual IList<WidgetTest> WidgetTests
    {
        get
        {
            IList<WidgetTest> widgetTests = new List<WidgetTest>();
            if (this.WidgetTest != null)
            {
                widgetTests.Add(this.WidgetTest);
            }
            return widgetTests;
        }
        set
        {
            if (value != null && value.Count > 1)
            {
                throw new Exception("The WidgetTests collection may not contain more than one item.");
            }
            else if (value != null && value.Count == 1)
            {
                this.WidgetTest = value[0];
            }
            else
            {
                this.WidgetTest = null;
            }
        }
    }
}
4
ответ дан 5 December 2019 в 23:15
поделиться

Когда вы скажите «предположить, что неуместно добавлять поля WidgetTest в Widget», вы имеете в виду в объектах вашего домена или в базе данных. Если вы довольны тем, что поля находятся в одной таблице в базе данных, как насчет сопоставления WidgetTest как компонента Widget? Пусть файл сопоставления NHibernate выглядит так:

<class name="Widget" table="Widget">
    ...
    <property name="WidgetProperty"/>
    ...
    <component name="WidgetTest" class="WidgetTest">
        <property name="WidgetTestProperty"/>
    </component>
</class>

Предоставление структуры таблицы:

WidgetTable
    WidgetProperty
    WidgetTestProperty

Что по-прежнему позволит вам иметь указанный вами общедоступный интерфейс, однако WidgetTest станет объектом значения, который вы можете или не хотите.

1
ответ дан 5 December 2019 в 23:15
поделиться