1

我有以下情况

在此处输入图像描述

一份 PurchaseOrder 有很多行项目,一张发票有很多行项目。 PurchaseOrder并且Invoice完全不同。如果一个特定的LineItem有一个PuchaseOrder,那么没有一个Invoice,反之亦然。我需要坚持这些关系。在我的应用程序中,我使用的是 NHibernate。

我想在数据库中,LineItems 表可以有一个带有外键的列 PurchaseOrder 和另一列带有外键的 Invoice。

最好的方法是什么?

4

3 回答 3

1

您的方法可以正常工作,因为您的 NHibernate 映射可以区分它们使用的外键。这种方法的唯一缺点是故意创建一个始终包含空数据的列。

另一种方法是拥有一个外键列和一个鉴别器列。然而,虽然从关系模型的角度来看这可能更清晰,但它会使 NHibernate 映射更加复杂。

于 2013-03-26T19:28:09.800 回答
0

您建议的解决方案是最好的,因为您只有 2 列相互排除。我的意思是您的 LineItem 属于 PurchaseOrder 或 Invoice,并且您没有特定于 PurchaseOrder LineItem 或 Invoice LineItem 的其他数据。

如果您想处理更接近对象类和一种继承的数据库表,那么有 EAV 模型,但在您的情况下它似乎过度设计。

实体属性值数据库与严格的关系模型电子商务

于 2013-03-26T19:45:47.283 回答
0

模型

您可以将 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; }
}

数据库

在数据库方面,您可以考虑将这两个项目映射到不同的表中,但这会不必要地增加连接。您可以为整个层次结构采用一个带有类型描述符的表。

  1. 特定的类有助于避免在其余代码中混淆哪个或哪个持有者LineItem可以为,并提高可读性。PurchaseOrderInvoice
  2. 您甚至可以通过添加PurchaseOrder作为参数来改进设计PurchaseLineItem(类似于Invoice作为构造函数参数InvoiceLineItem),以确保这些实体在没有它们各自的持有者的情况下不会被初始化。
于 2013-03-26T20:06:14.597 回答