views:

88

answers:

7

I have a table in my database called "OrderItemType" which has about 5 records for the different OrderItemTypes in my system. Each OrderItem contains an OrderItemType, and this gives me referential integrity. In my middletier code, I also have an enum which matches the values in this table so that I can have business logic for the different types.

My dev manager says he hates it when people do this, and I am not exactly sure why. Is there a better practice I should be following?

A: 

I don't see any problem in having enum values stored in the database, this actually prevents your code from dealing with invalid code types. After I started doing this I started to have fewer problems, actually. Does your manager offer any rationale for his hatred?

Otávio Décio
A: 

We do this, too. In our database we have an Int column that we map to an Enum value in the code.

Muad'Dib
+4  A: 

I do this all the time and I see nothing wrong with this. The fact of the matter is, there are values that are special to your application and your code needs to react differently to those values. Would your manager rather you hard-code an Int or a GUID to identify the Type? Or would he rather you derive a special object from OrderItem for each different Type in the database? Both of those suck much worse than an enum.

Jacob G
A: 

If you have a real business concern for each of the specific types, then I would keep the enum and ditch it in the database.

The reason behind this approach is simple:

Every time you add an OrderType, you're going to have to add business logic for it. So that justifies it being in your business domain somewhere (whether its an enum or not). However, in this case having it in the database doesn't do anything for you.

Joseph
You're assuming that OrderType is a calculated value based on the nature of the Order, otherwise, you wouldn't necessarily be able to rehydrate the object from the database.
Jacob G
@Jacob No I'm not assuming it's calculated, the user could just store it as a field in the OrderItem record, instead of having an entire child table to keep track of it. My point was there wasn't much of a need in creating an OrderItemType table, but he still needs to hold the enum value in the OrderItem.
Joseph
@Joseph: Ah, the "ditch it in the database" comment made it sound as though you were advocating removing it entirely. Sorry for misunderstanding. I like to keep that data normalized so that I can more easily alias it for display if necessary.
Jacob G
@Jacob ah yes, that would make sense, but that would be a separate requirement, with it's own concerns. But i definitely see your point.
Joseph
A: 

I have seen this done for performance reasons but I think that using a caching mechanism would be perferable in most cases.

CodeGrue
A: 

One alternative to help with the synchronization of the database values and the business logic enum values would be to use the EnumBuilder class to dynamically generate a .dll containing the current enum values from the database. Your business logic could then reference it, and have intellisense-supported synchonized enum values.

It's actually much less complicated than it sounds.

Here's a link to MSDN to explain how to dynamically build the enum.
http://msdn.microsoft.com/en-us/library/system.reflection.emit.enumbuilder.aspx

You just have to sub in the database access code to grab the enum values:

CuriousCoder
A: 

One more vote for you, I also use mapping database int <-> application enum, in addition, I usually describe my enums like this:

public enum Operation
{
    [Description("Add item")]
    AddItem = 0,

    [Description("Remove item")]
    RemoveItem = 1
}

which leaves me absolutely free to add new values without need to change database and with a very short workaround I can work i.e. with lists containing descriptions (that are very strongly tied to values!) - just a little bit of reflection reaches the goal!

In code, you can typically just add a property like this:

public class Order
{
    public int OrderTypeInt;

    public OrderTypeEnum OrderType
    {
        get { return (OrderTypeEnum)OrderTypeInt; }
        set { OrderTypeInt = (int)value; }
    }
}
Pz