我正在努力寻找建立1:0,1关系(“可能有一个”或“最多有一个”)关系的最佳方法。我相信这称为Z基数。
例如,假设我有两个类Widget
和WidgetTest
。并非所有Widget都经过测试,并且测试具有破坏性,因此每个Widget最多可以有一个WidgetTest。还要假设将WidgetTest字段添加到Widget是不合适的。
我希望我的公共(public)界面是:
Widget
WidgetTest { get; set; }
WidgetTest
Widget { get; }
模型1:Widget具有WidgetTest属性,并且在数据库中,Widget表具有WidgetTest的唯一受约束的外键。我的DBA争辩说,这将允许在没有Widget的情况下存在WidgetTest记录。
WidgetTable
WidgetTestId (FK, UQ)
模型2:Widget具有WidgetTest的私有(private)集合,并通过从由公共(public)WidgetTest属性控制的集合中添加或删除单个对象来实现0,1关系。数据库使用WidgetTest将其建模为1:m,它具有Widget唯一受约束的外键。我认为这意味着要采用适合数据库模式的模型(即对我来说需要更多工作)。
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);
}
}
}
}
最佳答案
我的方法是在映射中建立一对多关系的模型,但是将“许多”约束为一个项目。这允许可选的一对一,并且还可以确保在保存Widget时持久保存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;
}
}
}
}
关于nhibernate - 建模一对零或一种关系(Z基数),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2208796/