我有以下情况
一份 PurchaseOrder 有很多行项目,一张发票有很多行项目。
PurchaseOrder
并且Invoice
完全不同。如果一个特定的LineItem
有一个PuchaseOrder
,那么没有一个Invoice
,反之亦然。我需要坚持这些关系。在我的应用程序中,我使用的是 NHibernate。
我想在数据库中,LineItems 表可以有一个带有外键的列 PurchaseOrder 和另一列带有外键的 Invoice。
最好的方法是什么?
我有以下情况
一份 PurchaseOrder 有很多行项目,一张发票有很多行项目。
PurchaseOrder
并且Invoice
完全不同。如果一个特定的LineItem
有一个PuchaseOrder
,那么没有一个Invoice
,反之亦然。我需要坚持这些关系。在我的应用程序中,我使用的是 NHibernate。
我想在数据库中,LineItems 表可以有一个带有外键的列 PurchaseOrder 和另一列带有外键的 Invoice。
最好的方法是什么?
您的方法可以正常工作,因为您的 NHibernate 映射可以区分它们使用的外键。这种方法的唯一缺点是故意创建一个始终包含空数据的列。
另一种方法是拥有一个外键列和一个鉴别器列。然而,虽然从关系模型的角度来看这可能更清晰,但它会使 NHibernate 映射更加复杂。
您建议的解决方案是最好的,因为您只有 2 列相互排除。我的意思是您的 LineItem 属于 PurchaseOrder 或 Invoice,并且您没有特定于 PurchaseOrder LineItem 或 Invoice LineItem 的其他数据。
如果您想处理更接近对象类和一种继承的数据库表,那么有 EAV 模型,但在您的情况下它似乎过度设计。
您可以将 LineItem 映射为层次结构。
订单项层次结构
public class LineItem
{
//common properties of LineItem
}
public class PurchaseLineItem : LineItem
{
public PurchaseOrder PurchaseOrder { get; set; }
}
public class InvoiceLineItem : LineItem
{
public Invoice Invoice { get; set; }
}
修改 PurchaseOrder 和 Invoice 以引用特定子项
采购订单 :
public class PurchaseOrder
{
public IList<PurchaseLineItems> LineItems { get; set; }
}
发票 :
public class Invoice
{
public IList<InvoiceLineItems> LineItems { get; set; }
}
在数据库方面,您可以考虑将这两个项目映射到不同的表中,但这会不必要地增加连接。您可以为整个层次结构采用一个带有类型描述符的表。
LineItem
可以为空,并提高可读性。PurchaseOrder
Invoice
PurchaseOrder
作为参数来改进设计PurchaseLineItem
(类似于Invoice
作为构造函数参数InvoiceLineItem
),以确保这些实体在没有它们各自的持有者的情况下不会被初始化。