Cristhian Boujon
Cristhian Boujon

Reputation: 4190

Exclude columns in database and mapping with Nhibernate

I have the following situation

enter image description here

One PurchaseOrder has many line items and one Invoice has many line items. PurchaseOrder and Invoice are quite different. If a specific LineItem has one PuchaseOrder so hasn't an Invoice and vice versa. I need to persist these relationships. In my app I'm using NHibernate.

I thought on Database, the LineItems table could have a column with foreign key for PurchaseOrder and another column with a foreign key for Invoice.

What is the best approach for this?

Upvotes: 1

Views: 448

Answers (3)

frictionlesspulley
frictionlesspulley

Reputation: 12358

Model

You could map the LineItem as an heirarchy.

LineItem Heirarchy

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

Modify the PurchaseOrder and Invoice to refer the specific child

Purchase Order :

public class PurchaseOrder
{
    public IList<PurchaseLineItems> LineItems { get; set; }
}

Invoice :

public class Invoice
{
   public IList<InvoiceLineItems>  LineItems { get; set; }
}

Database

On the database side you could consider mapping the two items in different tables but this would unnecessarily increase joins. You could adopt a single table for entire heirarchy with a type descriminator.

  1. The specific classes help to avoid confusion in the rest of your code about which holder of the LineItem either PurchaseOrder or Invoice is nullable and improve readability.
  2. You could even improve the design by making adding PurchaseOrder as a parameter on PurchaseLineItem (similarly Invoice as a constructor parameter for InvoiceLineItem) to make sure that these entities are not initialized without their respective holders.

Upvotes: 0

Thomas
Thomas

Reputation: 1

The solution you suggest is the best, because you just have 2 columns mutually excluded. I mean either you LineItem belongs to a PurchaseOrder or to an Invoice and you don't have other data specific to PurchaseOrder LineItem nor to Invoice LineItem.

If you want to deal with database tables closer to object classes and a kind of inheritance, then there is the EAV model, but it seems over-engineered in your case.

Entity Attribute Value Database vs. strict Relational Model Ecommerce

Upvotes: 0

David Osborne
David Osborne

Reputation: 6781

Your approach will work fine as your NHibernate mappings can discriminate on which foreign key they use. The only downside to this approach is knowingly creating a column that will contain null data all of the time.

An alternative is to have one foreign key column and a discriminator column. However, while this might be cleaner from a relational model point of view, it will make the NHibernate mapping more complicated.

Upvotes: 1

Related Questions