views:

501

answers:

6

I have a data object (let's say it's called 'Entry') that has a set of potential states that look something like this:

1 - Created
2 - File added
3 - Approved
4 - Invalid

This is represented in the database with a 'Status' table with an autonumber primary key, then a 'StatusId' field in the main table, with the appropriate relationships set up.

In my (custom) data layer, I have the 'Entry' object, and, currently, I also declare an Enum with the states listed above specified. Finally I declare a private instance of this Enum along with the appropriate public property.

In my 'Commit()' method I cast the instance of the Enum to an integer and pass it to an Update stored procedure.

In my static 'GetEntry()' method I will obviously have an integer passed back from the database. I then use the 'Enum.Parse()' method to extract an object which is an instance of my Enum which corresponds to the returned status integer. I cast this to the type of my Enum and assign it to the local private variable.

My question is pretty simple - is this approach appropriate, and if not what alternative, other than just storing the raw integer value (which i'm not necessarily averse to), is better.

My reason for asking is that this all just seems incredibly messy to me, what with all the casting and maintaining two lists of the same set of values. I accept the benefit lies in a better experience for the consumer of the data object, but even so...

Thanks!

+1  A: 

That method seems fine to me.

In the past I've done the same thing but also had a table that contained a row for each member of the enum that table was then the foreign key for any table that used the enum value, just so someone reading the database could understand what each status was without having to see the actual enum.

for example if I had an enum like

enum status
{
    Active,
    Deleted,
    Inactive
}

I would have a table called status that would have the following records

ID   Name
0    Active
1    Deleted
2    Inactive

That table would then be the foreign key to any tables that used that enum.

Gavin Draper
"This is represented in the database with a 'Status' table with an autonumber primary key" ;-)
Steven A. Lowe
Yes, and this would not work as enums start numbering at 0 by default. Good luck fixing the states :)
leppie
my bad, fixed :)
Gavin Draper
A: 

the database lookup table is necessary; the programmatic enum is convenient to avoid having 'magic numbers' in the code

if your code does not need to manipulate the status, however, then the enum is unnecessary

Steven A. Lowe
A: 

I do this approach with Enums all the time. If it is a simple item like status that is not expected to change ever I prefer the Enum. The parsing and casting is a very low impact operation.

I have been doing this successfully with Linq to Sql for sometime now with no issues. Linq will actually convert from Enum to int and back automatically.

Code is more than just about speed but readability. Enums make code readable.

To answer your question directly this is a very valid apporach.

David Basarab
+3  A: 

Hi,

We have something familiar in one of our projects. We have a table containting types of items. These types have an id, in the code we have an enum with the same id's. The thing is, in the database we don't use autonumber (identity) so we have full control of the id. And when saving our object we just take the id of the enum to save the object. I also thought this approach was messy but it's not that bad afterall.

Sem Dendoncker
I agree with the statement about not using an identity on the status ids
Pedro
A: 

If your code requires setting known "Status" values (which you've defined in your enum), then it's probably also a requirement that those "Status" values exist in the database. Since they must exist you should also have control over the Status_ID assigned to each of those values.

Drop the identity and just explicitly set the lookup value IDs.

Joseph Daigle
+1  A: 

Yup this is fine!

PLEASE always explicitly set the values like this. That way if someone ever goes to add something they'll realize the values are important and shouldn't be messed with.

enum status
{
    Active = 1,
    Deleted = 2,
    Inactive = 3
}

If you're passing the value around via WCF I'd recommend adding

  NULL = 0

Otherwise if you try to serialize a 0 coming from the database you'll get a horrible error and it'll take you forever to debug.

Simon_Weaver
+1 for the WCF note - one of those things you either know to avoid or it kills your project for a week. My approach has been to just start assigning IDs at 0 (ie. Active = 0 in this case). Neither code nor database cares, after all.
djacobson
@djacabson +1 for 'kills your project for a week'
Simon_Weaver