How to save enum in database as string

.net c# c#-4.0 entity-framework

Question

This is my Model Class where we have a Type which could be a Zombie or Human

public class User
{
    public int ID { get; set; }
    public string Name { get; set; }
    public Type Type { get; set; }
    public List<Wepon> WeposInList { get; set; }
    }  

public enum Type
{   [Description("Zombie")] Zombie,
    [Description("Human")] Human
}

Currently it is saving data in Int

enter image description here

I want to save the data as Human and Zombie, not with int

1
27
12/7/2015 10:34:26 AM

Accepted Answer

I had this problem as far as I remember and honestly I don't know why didn't MS add this feature (NH can do it like since always..).

Any ways, what I usually did is use const strings classes like:

public static class MyEnum
{
    public const string Foo = "Foo";
    public const string Bar = "Bar";
}

public class Client
{

    public string MyVal { get; set; }

    public Client()
    {
        MyVal = MyEnum.Bar;
    }

}

Cons - as simple as can be.

Downsides - you loose type checking (though it could be enforced programmatically).


So this time I tried to think of something more ambitious. So I took the concept described by Brian (which has some downsides when e.g. a given enum is used widely across the domain). And well.. I got the following working:

A base component class to store the values:

[ComplexType]
public class DbEnum<TEnum>
{
    public string _ { get; set; }

    public DbEnum()
    {
        _ = default(TEnum).ToString();
    }

    protected DbEnum(TEnum value)
    {
        _ = value.ToString();
    }

    public TEnum ToEnum()
    {
        return _.ToEnum<TEnum>();
    }

    public static implicit operator DbEnum<TEnum>(TEnum value)
    {
        return new DbEnum<TEnum>(value);
    }

    public static implicit operator TEnum(DbEnum<TEnum> value)
    {
        return value.ToEnum();
    }
}

... which would be basically sufficient.. except EF doesn't support generic types...

This means for every enum you have to have something like...

public enum PrivacyLevel
{
    Public,
    Friends,
    Private
}

public class PrivacyLevelEnum : DbEnum<PrivacyLevel>
{
    public PrivacyLevelEnum() : this(default (PrivacyLevel))
    {      
    }

    public PrivacyLevelEnum(PrivacyLevel value) : base(value)
    {
    }

    public static implicit operator PrivacyLevelEnum(PrivacyLevel value)
    {
        return new PrivacyLevelEnum(value);
    }

    public static implicit operator PrivacyLevel(PrivacyLevelEnum value)
    {
        return value.ToEnum();
    }
}

Which gives you some boiler-plate that could be easily generated e.g. using T4 templates.

Which finally ends you up with using:

public class CalendarEntry : Entity
{

    public virtual PrivacyLevelEnum PrivacyLevel { get; set; } = new PrivacyLevelEnum();

}

But since you have implicit conversion in place, class declarations are the only ones to be aware of the helper types.

8
11/22/2016 11:25:35 AM

Popular Answer

You can save the enum to the db as a string, and I agree with dotctor that it is not the best idea, but if you need to, you need to make a few changes.

public class User
{
    public int ID { get; set; }
    public string Name { get; set; }
    public List<Wepon> WeposInList { get; set; }

    [Column("Type")]
    public string TypeString
    {
       get { return Type.ToString(); }
       private set { Type= value.ParseEnum<Type>(); }
    }

    [NotMapped]
    public Type Type { get; set; }
}  

Add this extension class to your project.

public static class StringExtensions
{
    public static T ParseEnum<T>(this string value)
    {
        return (T)Enum.Parse(typeof(T), value, true);
    }
}

Full details are here - http://NoDogmaBlog.bryanhogan.net/2014/11/saving-enums-as-strings-with-entity-framework/



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow