Enum synced with Database
So your Init threw me off, initially I thought this class was doing something, but it was doing something else (not your fault, totally mine).

Here's how I would handle this:


Get rid of asDBType and just return the Status, we'll see how in a moment.
Don't call the private member type if the database member is Name, call it name.
Use CallerMemberNameAttribute so you don't need a magic string.


You want type-safety at compile time, against something that's inherently unsafe, so we have to cheat quite a bit to make that happen.

We're also going to use some Reflection - doing so means we can eliminate the List&lt;StatusEnum&gt; members, and replace a lot of this class with a couple quick calls.

public class StatusEnum
{
    private static Dictionary&lt;string, Status&gt; _lookup = new Dictionary&lt;string, Status&gt;();
    private static Status _get([CallerMemberName]string name = null) =&gt;
        _lookup.Length &gt; 0 ? _lookup[name] : throw new InvalidOperationException($"The method '{nameof(Init)}' has not been called.");
        // `CallerMemberNameAttribute` gives us the name of whatever
        // method or property called this method, which means since
        // our property calls `_get()`, we get the name of that
        // property implicitly

    public static Status ACTIVE =&gt; _get();
    public static Status COMPLETED =&gt; _get();
    public static Status DELETED =&gt; _get();
    public static Status INPROGRESS =&gt; _get();

    public static void Init(ECIContext ctx)
    {
        foreach (var prop in typeof(StatusEnum).GetProperties())
        {
            var name = prop.Name;

            // Assuming `ctx.Status` has a `SingleOrDefault`
            var status = ctx.Status.SingleOrDefault(x =&gt; x.Name == name);
            if (status == null) { throw new ArgumentException($"The value '{name}' is not a valid '{nameof(Status)}'."); }

            _lookup.Add(name, status);
        }
    }
}


Realistically, your StatusEnum class is a bunch of helper stuff, so you don't really need instance members, and you don't really want to keep an instance of this class, you care about the Status class. This is similar to how I do Setting objects in Entity Framework, though my setup was more complex.

Your version requires adding a property with a self-referencing name, this version eliminates that.


public static Status ONHOLD =&gt; _get();
public static readonly StatusEnum ONHOLD = new StatusEnum("ONHOLD");



Also, in your version, C#6.0 introduced nameof() which would allow you to safely initialize:

public static readonly StatusEnum ACTIVE = new StatusEnum(nameof(Active));


The other advantage to this version is you'll always be sure that you have a valid Status object, no need to asDBType, which means we can make this generic for your other situations:

public abstract class ItemizedEnum&lt;TItem, TClass&gt;
    where TClass : ItemizedEnum&lt;TItem, TClass&gt;
{
    private static Dictionary&lt;string, TItem&gt; _lookup = new Dictionary&lt;string, TItem&gt;();
    protected static TItem Get([CallerMemberName]string name = null) =&gt;
        _lookup.Count &gt; 0 ? _lookup[name] : throw new InvalidOperationException($"The '{nameof(Init)}' method MUST be called first.");

    protected abstract TItem GetFromDatabase(ECIContext ctx, string name);

    public static void Init(ECIContext ctx)
    {
        var classInstance = Activator.CreateInstance&lt;TClass&gt;();
        foreach (var prop in typeof(TClass).GetProperties())
        {
            var name = prop.Name;
            var obj = classInstance.GetFromDatabase(ctx, name);
            if (obj == null || obj.Equals(default(TItem)) == true) { throw new ArgumentException($"The value '{name}' is invalid for '{typeof(TClass).Name}'"); }
            _lookup.Add(name, obj);
        }
    }
}


Finally, in StatusEnum:

public class StatusEnum : ItemizedEnum&lt;Status, StatusEnum&gt;
{
    public static Status ACTIVE =&gt; Get();
    public static Status COMPLETED =&gt; Get();
    public static Status DELETED =&gt; Get();
    public static Status INPROGRESS =&gt; Get();

    protected override Status GetFromDatabase(ECIContext ctx, string name) =&gt;
        ctx.Status.FirstOrDefault(x =&gt; x.Name == name);
}


This decreases the level of redundancy, the class only needs to implement a GetFromDatabase(ECIContext, string) method, and we now no longer care about any of that in StatusEnum itself, just what values it contains. We can then build other ItemizedEnum classes:

public class StateEnum : ItemizedEnum&lt;State, StateEnum&gt;
{
    protected override State GetFromDatabase(ECIContext ctx, string name) =&gt;
        ctx.State.FirstOrDefault(x =&gt; x.Title == name);

    public static State OtherTest =&gt; Get();
}


And we get the same type-safety. Now a test of your live examples might be:


public class StatusEnum : ItemizedEnum&lt;Status, StatusEnum&gt;
{
    protected override Status GetFromDatabase(ECIContext ctx, string name) =&gt;
        ctx.Status.FirstOrDefault(x =&gt; x.Name == name);

    public static Status Test =&gt; Get();
}

public class StateEnum : ItemizedEnum&lt;State, StateEnum&gt;
{
    protected override State GetFromDatabase(ECIContext ctx, string name) =&gt;
        ctx.State.FirstOrDefault(x =&gt; x.Title == name);

    public static State OtherTest =&gt; Get();
}

StatusEnum.Init(new ECIContext());
StateEnum.Init(new ECIContext());
Console.WriteLine(StatusEnum.Test.Name);
Console.WriteLine(StateEnum.OtherTest.Title);