建模一对零或一种关系(Z基数) [英] Modeling one to zero or one relationships (Z cardinality)

查看:53
本文介绍了建模一对零或一种关系(Z基数)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力寻找建立1:0.1关系的最佳方法(可能有一个"或最多有一个").我相信这称为Z基数.

I'm struggling to find the best way to model 1 : 0,1 relationships ("may have one" or "has at most one"). I believe this is called Z cardinality.

例如,假设我有两个类WidgetWidgetTest.并非所有Widget都经过测试,并且测试具有破坏性,因此每个Widget最多可以有一个WidgetTest.还要假设将WidgetTest字段添加到Widget是不合适的.

For example, suppose I have two classes Widget and WidgetTest. Not all Widgets are tested and the test is destructive so there can be at most one WidgetTest per Widget. Also assume that it's inappropriate to add the WidgetTest fields to Widget.

我希望我的公共界面是:

I would like my public interface to be:

Widget
    WidgetTest { get; set; }

WidgetTest
    Widget { get; }

模型1:Widget具有WidgetTest属性,并且在数据库中,Widget表具有WidgetTest的唯一受约束的外键.我的DBA认为这将允许在没有Widget的情况下存在WidgetTest记录.

Model 1: Widget has a WidgetTest property and in the database the Widget table has a uniquely constrained foreign key to WidgetTest. My DBA argues that this would allow a WidgetTest record to exist without a Widget.

WidgetTable
    WidgetTestId (FK, UQ)

模型2:Widget具有WidgetTest的私有集合,并通过从由公共WidgetTest属性控制的集合中添加或删除单个对象来实施0,1关系.数据库使用WidgetTest将其建模为1:m,它具有Widget唯一受约束的外键.我认为这意味着要采用适合数据库模式的模型(即,对我来说更多的工作).

Model 2: Widget has a private collection of WidgetTest and enforces the 0,1 relationship by adding or removing a single object from the collection controlled by a public WidgetTest property. The database models this as 1:m with WidgetTest having a uniquely constrained foreign key to Widget. I argue that this means adopting the model to fit the database schema (i.e. more work for me).

WidgetTestTable
    WidgetId (FK, UQ)

哪种模式更好?使用NHibernate哪个更容易实现?还是有第三种方式?

Which model is better? Which is easier to achieve with NHibernate? Or is there a third way?

编辑...这就是我的最终结论:

Edit ... Here's what I ended up with:

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);
            }
         }
     }
}

推荐答案

我的方法是在映射中建立一对多关系的模型,但将许多"约束为一个项目.这允许可选的一对一,并且还可以确保在保存Widget时持久保存WidgetTest实例.例如:

My approach has been to model a one-to-many relationship in the mappings, but to constrain the "many" to a single item. This allows the optional one-to-one, and also guarantees that your WidgetTest instance is persisted when you save the Widget. For example:

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;
            }
        }
    }
}

这篇关于建模一对零或一种关系(Z基数)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆