我有以下情况

一份 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可以为空,并提高可读性。PurchaseOrderInvoicePurchaseOrder作为参数来改进设计PurchaseLineItem(类似于Invoice作为构造函数参数InvoiceLineItem),以确保这些实体在没有它们各自的持有者的情况下不会被初始化。