Here's the proc I created and below is the explanation of how I went about doing this: http://heathesh.com/code/sql/GenerateEnumClass.txt
I'm sure every c# developer has come across a situation where they have a lookup table that they'd like to convert into an enum in code. I've actually had to do it a few times myself and each time I use some sort of cursor and t-sql to create the enum class code. So I figured why not create a procedure to do this that I could re-use?
To begin with, there's a few parameters I needed to pass into the procedure. These were:
- The table name
- The namespace I wanted of the code
- The DataContract namespace. Because most of the stuff I do now is WCF this was a necessity but you can obviously remove this if you want.
- The id field on the lookup table.
- The value field on the lookup table.
I've attached the proc for you to copy (http://heathesh.com/code/sql/GenerateEnumClass.txt). The basics of how it works is that I insert the id and value fields into a temporary table using sp_executesql, then loop through the values using a cursor and simply use print statements to output the relevant code.
To use the proc I created a simple table called Title with an Id and a Name column like so:
CREATE TABLE [dbo].[Title](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NOT NULL,
CONSTRAINT [PK_Title] PRIMARY KEY CLUSTERED
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
I then populated the table with values like so:
INSERT INTO [Title] ([Name]) VALUES ('Mr')
INSERT INTO [Title] ([Name]) VALUES ('Mrs')
INSERT INTO [Title] ([Name]) VALUES ('Miss')
INSERT INTO [Title] ([Name]) VALUES ('Dr')
INSERT INTO [Title] ([Name]) VALUES ('Prof')
INSERT INTO [Title] ([Name]) VALUES ('Sir')
INSERT INTO [Title] ([Name]) VALUES ('Madam')
INSERT INTO [Title] ([Name]) VALUES ('Mr And Mrs')
You'll notice one of the values has spaces in it. Since enum names cannot have spaces in it when you run the proc you'll notice in the output that it adds the Description attribute with the full name of the row, this is so you can still get the value of the string. If you need help with this check out a previous post of mine on reading the description attribute: Reading the DescriptionAttribute of enumerators ...
Then I simply ran my proc like so:
'Title', -- this is the name of the lookup table
'Heathesh.Com.Entity', -- this is the namespace I wanted to appear in the code
'http://heathesh.com/entities', -- this is the data contract namespace I wanted to appear in the code
'Id', -- this is the id field of the table
'Name' -- this is the name field of the table
And this produced my required output like so:
/// Title enum
[DataContract(Name = "Title", Namespace = "http://heathesh.com/entities")]
public enum Title
Mr = 1,
Mrs = 2,
Miss = 3,
Dr = 4,
Prof = 5,
Sir = 6,
Madam = 7,
[Description("Mr And Mrs")]
MrAndMrs = 8,
I simply then added a "Title.cs" class to my project, replaced all the code in the class with what was generated and that was it. An enum class generated using sql from a lookup table.
Please note: Don't forget to add a reference to "System.Runtime.Serialization" in your project for the WCF stuff (DataContract, DataMember, EnumMember etc.)