Build Enum from database query
So your function should return a list of enums:
private List<DrugColor> BuildEnum()
Thats the first thing.
When you declar the list you return, change it to a list of enum too:
List<DrugColor> EnumList = new List<DrugColor>();
When you take the data from the database, each read() is a color so color name is a DrugColor
DrugColor colorName;
colorName = new DrugColor{(DrugColor)Enum.Parse(typeof(DrugColor ),rdr["Color"].ToString()); }
With this you parse the string into the enum.
And then you add it to the list
Voila!
EDIT:
Your enum should contain things:
enum DrugColor
{
Red,
Blue,
Yellow
}
Code First Enumerations put into Lookup Tables
So I am not going to lie, my solution is a bit in-depth but I have been using it now for the past few days and I find it works exactly as I need it to.
Let's start at the top, my base class I created:
public abstract class LookupTableBase
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
[Required]
public string Name { get; set; }
}
Here is an example of one of my lookup table Entity Models:
/// <summary>
/// Lookup Table for Enumeration AddressTypes
/// File Reference: DataAccessLayer/Enumerations/Locators.cs
/// DO NOT USE
/// SHOULD NOT BE AVAILABLE IN ENTITY MODELS
/// </summary>
[Table("AddressTypes", Schema = "Lookup")]
public class AddressType : LookupTableBase {}
Here is the Enum that goes with this Lookup Table:
public enum AddressTypes
{
[StringValue("")]
Unknown = 0,
[StringValue("Home")]
Home = 1,
[StringValue("Mailing")]
Mailing = 2,
[StringValue("Business")]
Business = 3
}
The StringValue Attribute is a custom attribute I created (based on examples I found online) that allow me to call:
AddressTypes.Home.GetStringValue();
Which will return the string value: Home
.
I add the Lookup Entity Model to my DbSets so the table will be created but I never directly reference the Lookup Entity Models in any of my other Entity Models. Its sole purpose is to create lookup tables in the DB so that I can create Foreign Key Constraints against them.
public DbSet<AddressType> AddressTypes { get; set; }
In my OnModelCreating Method for my Context, I did have to add this because the Data Annotation did not seem to hold all the way through:
modelBuilder.Entity<AddressType>()
.Property(x => x.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
In my Migration's Configuration file, I add this into the Seed Method:
var addressTypeCount = Enum.GetValues(typeof (AddressTypes)).Length;
var addressTypes = new List<AddressType>();
for (var i = 1; i < addressTypeCount; i++) {
addressTypes.Add(new AddressType {
Id = i,
Name = ((AddressTypes)i).GetStringValue()
});
}
context.AddressTypes.AddOrUpdate(c => c.Id, addressTypes.ToArray());
context.SaveChanges();
Last, in the Migration file itself I move all the lookup table creation methods to the top of the list, now I can add Foreign Key Constraints to any table that references that enum. In my case, I took it one step further. Since the Migration Class is a partial, I created another partial class to match it. Created two methods:
public void LookupDataUp()
public void LookupDataDown()
In the LookupDataUp method, I add all my custom Foreign Keys and Indexes and in the LookupDataDown I Remove all my custom Foreign Keys and Indexes.
When I run Update-Database, all my tables that used to have some integer value that represented something (in this case an AddressType) but had no real value, now have a value that can be seen by linking it to its lookup table.
I will admit, this seems like a lot of work just to get some small amount of data into the database but now every time I remove/change/add new items to my enum, it's automatically pushed to the DB. Plus as I stated in the above question, this creates database integrity by having the foreign key constraint on the 'integer' field.
Populate an enum with values from database
No. Enums are always fixed at compile-time. The only way you could do this would be to dyamically generate the relevant bytecode.
Having said that, you should probably work out which aspects of an enum you're actually interested in. Presumably you weren't wanting to use a switch
statement over them, as that would mean static code and you don't know the values statically... likewise any other references in the code.
If you really just want a map from String
to Integer
, you can just use a Map<String, Integer>
which you populate at execution time, and you're done. If you want the EnumSet
features, they would be somewhat trickier to reproduce with the same efficiency, but it may be feasible with some effort.
So, before going any further in terms of thinking about implementation, I suggest you work out what your real requirements are.
(EDIT: I've been assuming that this enum is fully dynamic, i.e. that you don't know the names or even how many values there are. If the set of names is fixed and you only need to fetch the ID from the database, that's a very different matter - see Andreas' answer.)
Dynamically create an enum
Probably, you should consider using a Dictionary<string, int>
instead.
If you want to generate the enum
at compile-time dynamically, you might want to consider T4.
Creating an enum/class from a Database Table
You will have to generate an assembly if you want to be able to use the enumeration or class at compilation time. Reflection happens at execution time so that won't give you intellisense.
This is a common problem - there are a set of distinct values in a database table and those values don't change often so they are modeled as an enum
in the source code. This allows these somewhat static values to be easily used in a very readable way. The problem is that when the values do change, it would be nice if the enum
changed as well.
The problem with trying to keep the enum
and database in sync is that an automatic process doesn't change the fact that if you are changing the database it would be very unlikely that you would do so without having to roll new code to leverage the changed value. It is better to model these values as an enum
and still store them in the database. Just manually sync them as the need arises.
Can I create an enum that has more than 500 members?
Can I create an enum in C# (.net) that has 500 members
Sure, if you want to.
But I think it's a bad idea. Imagine if someone else wants to use your Database, they'll then have to have a copy of the same enum
, which means you'll have to maintain 2 (or more) copies of the same list as long as other people need it and I don't think anyone wants to do that.
500 rows in a Database is like nothing, making it into an enum
won't help you that much (at least not something you can notice), instead just store them in a Table and everyone is happy.
Is there a way to localize the values in enums
No, not out-of-the-box. You will have to create your own solution for this. It depends on where and how your localizations are stored.
Generate Enum from Lookup Tables - EF 6
One way is with a T4 Template that will automatically generate your Enum's from the table.
Here is a great template that I've used in a couple projects. Just change the connection string, and make sure the scripts assumptions about the format of your data are correct (i.e. that the id's are named TableNameID
). Then add in the appropriate .tt files for each Enum, and run the template.
Related Topics
How to Set Cursor Position in Gtk -Linux, Monodevelop
Capture Stored Procedure Print Output in .Net
How to Load an Assembly to Appdomain with All References Recursively
All Possible Combinations of a List of Values
Entity Framework Change Connection at Runtime
Intersection of Multiple Lists with Ienumerable.Intersect()
How to Stop C# Console Applications from Closing Automatically
How to Bind Wpf Button to a Command in Viewmodelbase
What Are the Differences Between Delegates and Events
Ignoring a Class Property in Entity Framework 4.1 Code First
Reading PDF Content Using Itextsharp in C#
How to Access Named Capturing Groups in a .Net Regex
Copying from and to Clipboard Loses Image Transparency
Update .Net Web Service to Use Tls 1.2
How to Update Gui with Backgroundworker
How to Generate and Validate a Software License Key