Take the 2-minute tour ×

I am wondering how people handle the following scenario (this is hypothetical to get the idea across)...

  • TABLE A (Orders): OrderId, StatusId, etc (foreign key on status table)
  • TABLE B (Statuses): StatusId, Name, etc

Table B Needs to exist (IOW, I can't just create an enum of statuses for example), because the order status list needs to be dynamic as business needs and practices change and you have methods in your program like GetAllOrders(), GetAllStatuses(), GetOrderByStatus(int statusId), etc. However, it seems like you continually need to access a "hard coded" status. For example, when an order is first created it's status is "New" and you need to set it to that status without any user intervention. Perhaps you have a GetUnfilledOrders report that returns all orders that are "processing", again without having the user select the status they're looking for because the name of the report implies what they want. I hope you get the idea.

What I've been doing in these cases is creating a setting such as DefaultNewOrderStatus (int) and setting it to the id of the status I'd like to use for new orders, or StatusesForUnfilledOrdersReport (int[]) and again setting a list of statuses to use. The idea being that I can change these settings on the fly if our status "architecture" changes. The issue is that the number of "hard coded" values needing to be used seems to grow (maybe now I need a default status to set fulfilled orders to, or a list of statuses to use to display an "Open" orders UI view, etc) and along with it, so do the number of settings to handle them.

I'm extremely interested in knowing how others out there handle these situations?

share|improve this question
Whats wrong with hard-coding status values (as an enum) in the first place? –  usr Sep 17 '12 at 18:51
In this hypothetical scenario, as I indicated, order "statuses" needs to be "fluid" so that it can be modified as business practices or requirements change. (i.e. maybe someone decides that "New" order should really be "Recently Received" or we need to have a "On Backorder" status added). With a hard coded enum, the program would have to be recompiled and deployed every time a change was required. –  Scott Harris Sep 17 '12 at 18:59
@ScottHarris Your title of "Hard Values" is the opposite of "Fluid" –  Blam Sep 17 '12 at 19:01
It's a trade off between normalization and coupling to code. If you 'hard code' values in the code, you've become decoupled from the database. Which is good in one respect; but bad in another: new values require a recompilation. If they truly are hard-coded, don't put them in their own table at use an "int" column. If you can't, don't use hard-coded values in the code. –  Peter Ritchie Sep 17 '12 at 19:03
@Blam, that's my dilemma. I am looking to see how people handle a situation where the list in question needs to be fluid and access specific "hard" values from it for certain tasks. –  Scott Harris Sep 17 '12 at 19:04

4 Answers 4

I'm not sure if I caught the point of your question, but it looks like you are trying to implement Business Process Manager in a "Hard coded" way. What you actually need is not a dynamic list of statuses, but dynamic list of processes which are in fact scenarios of how to use statuses. Additionally you need actions, which will trigger statuses change. So, lets take for example, you have a list of statuses:

  1. NEW

Next, a list of actions:


Now, you can design a process:

  • [START] -> (CREATE NEW) -> NEW

Your application needs to have a set of methods which can operate upon the above (forms usually, some wizards, etc.). When something changes, you add new statuses, copy and modify the process and your application already know how to deal with it, for example you need to deal with cancellation of your order. You add CANCEL to your actions, CANCELLED to your orders and create new process (or modify the old one) adding:


So, to sum up, your problem is not the status change only, but the change in a business process. In that case you need to have dynamic processes, not only statuses. Than, the problem disappears - but you need to rebuild your application- or rather build a new application.


Regarding the reports, it's a rather different situation. If you find a way to prepare generic architecture that is capable of generating any report you will be reach as you will challenge the actual form of Business Intelligence, data warehousing concept, etc. :-)

share|improve this answer
This looks exactly what I am after. You're right, I've been thinking about it entirely wrong! Now, I have never implemented anything like this before. Do you store your "actions" in the database and map them somehow in your application? Same with your processes, do you store them in the database and map them in your application? Do you have links to any references I could read through to better understand how to implement something like this? –  Scott Harris Sep 17 '12 at 19:41
This is in fact not an easy thing to do, but can be applied to many different businesses - as usually with generic solutions. There is a lot of different tools like that, they're so called BPMs (Business Process Managers), you can google some examples, or even look on YouTube how it works. I have worked with one of them, it's called Metastorm (OpenText now I guess). Back to your question, how is it implemented is a really metter of particular case, as I stated the more generic, usually the better, but also more complicated and harder to develop and maintain. –  WojtusJ Sep 17 '12 at 20:01

Make the Enum. This enum is for your business logic. You can still present the list of available status from the database query.

When you convert the StatusId to an StatusEnum value, you will need to have a case for a new value in the database. However, all of your logic should be fine, because New will still be New. If you need to write logic that uses a newly created status, update the Enum.

For something like a status, there is no reason the StatusId should ever change on an existing row. If rows are removed, your Enum is fine, that value will just never be used. You can remove it when you are doing some other maintenance.

share|improve this answer

This is how I handle it. The common scenario is int, string with int as a key. Read the fluid list into a Dictionary in ctor. So I define fluid as they need to restart the app to get a fresh list.

    public static Dictionary<int, string> FluidStatus { get; private set; }  // poulate in ctor
    public class FluidBus
        public Int32 ID { get; set; }  // in set need error checking the ID is in range
        public String Status { get { return FluidStatus[ID]; } }  // need to check the ID is in range
        public FluidBus() { ID = 0; } // default
        public FluidBus(Int32 id) { ID = id; }
        // alternative is to pass a reference to Dictionary in the ctor as then  
        // can change out the status without changing the class

Actually I mainly use it with SysName and DispName with a rule SysName can have no spaces. DispName is what the user sees. But for like XML export I use SysName. That way admin people can deal with the user whims and keep some some semi static names for them.

If it is a status the program needs to use then Enum every time. On the SQL side I will have a FK table not used by C# but as a common constraint and for when I am in SQL I can look up the name.

share|improve this answer

I like @WojtusJ answer, anyway there is also another option:

You can create a status settings page where You will be able to set a concrete statusId for status situation, so it would look like this:

New status:         [Select a status]
Received status:    [Select a status]
Processing status:  [Select a status]
Complete status:    [Select a status]

And You will store these settings by a key, like 'new', 'received', etc. Then You can get the statusId of the 'new' status for new order and continue - does not matter that 'new' statusId reffers to status with name Completed.

share|improve this answer

Your Answer


