Question

When modelling an Order does it help to have a property for Product in the Orderline or would just the Product Name be needed?

The Order:

public class Order 
{
    public Guid Id {get; set;}
    public DateTime OrderDate {get; set;}
    public Decimal Total {get;set;}
}

Orderline:

public class Orderline
{
    public Guid Id {get; set;}
    public Order Order {get; set;}
    public Product Product {get; set;}
    public int Quantity {get; set;}
    public Decimal Price {get; set;}
}

With this if I delete a Product it would either need to cascade delete the Orderline and Order (which would be really bad) or I soft delete and set an IsDeleted flag on the Product.

Certainly having the relationship present in a domain model can be helpful; so from an Order I can access it's Orderlines and then into the Product for each line and access all the properties of the Product. But as the Orderline has properties for price, quantity this dependency on the Product seems to hurt more than it helps. If I change the Orderline so it only has the name of the product (in the class below I've changed the type from Product to String, then I could delete a product without affecting any records of it:

public class Orderline
{
    public Guid Id {get; set;}
    public Order Order {get; set;}
    public string Product {get; set;}
    public int Quantity {get; set;}
    public Decimal Price {get; set;}
}
Was it helpful?

Solution

I would suggest that your simply copy the product information to the order line. Products have a tendency to change over time, and what you really want is a snapshot of what the customer bought at the specific time.

OTHER TIPS

It really depends on your situation. If you need to delete the orderline if a order is deleted then by reference is correct. I would do it by reference. It is simple and fast instead of getting order through the ordername which is an extra step. I don't even know how orderline is different from order. I think there should be just one order, condense. If things are saved in sql, do a foreign key identity, if everything is done in c#, reference is fine.

If memory serves, well-established sales systems like Dynamics GP do both. You need to know what the state of the product was at the time of order; but it's also useful to be able to link a line item to the originating product. For instance, with any given product you might at some time need to compile a list of customers who purchased the product. Or, if the name of a product changes, you may need to be able to determine, for purposes of fulfillment, what the product "is."

That said, what the product "is" shouldn't change. And products which have been ordered should generally never be deleted. But, you ideally also know the exact phrasing, description, pricing, etc. that were on a customer's invoice.

In code, it's a matter of preference, as long as you fulfill the best practices under the hood. I'd suggest having two full Product objects on each OrderLine:

public class Orderline
{
    public Guid Id {get; set;}
    public Order Order {get; set;}
    public Product Product {get; set;}
    public Product OriginalProduct {get; set;}  // or "OriginatingProduct" or whatever
    public int Quantity {get; set;}
    public Decimal Price {get; set;}
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top