Map string column in Entity Framework to Enum
Solution 1
It is ugly, but for mapping enums to strings I found something like this:
public virtual string StatusString
{
get { return Status.ToString(); }
set { OrderStatus newValue;
if (Enum.TryParse(value, out newValue))
{ Status = newValue; }
}
}
public virtual OrderStatus Status { get; set; }
OrderStatus is the enumerator type, Status is the enumerator and StatusString is the string version of it.
Solution 2
Probably a nicer version.
OrderStateIdentifier field is used for both JSON serialization and database field, while OrderState is only used in the code for convenience.
public string OrderStateIdentifier
{
get { return OrderState.ToString(); }
set { OrderState = value.ToEnum<OrderState>(); }
}
[NotMapped]
[JsonIgnore]
public OrderState OrderState { get; set; }
public static class EnumHelper
{
/// <summary>
/// Converts string to enum value (opposite to Enum.ToString()).
/// </summary>
/// <typeparam name="T">Type of the enum to convert the string into.</typeparam>
/// <param name="s">string to convert to enum value.</param>
public static T ToEnum<T>(this string s) where T: struct
{
T newValue;
return Enum.TryParse(s, out newValue) ? newValue : default(T);
}
}
Solution 3
You can do either:
Decorate the Enum property in your class as a text column
[Column(TypeName = "nvarchar(50)")]
public FileTypes FileType { get; set; }
OR
in your DatabaseContext
class, override the OnModelCreating
and add:
modelBuilder
.Entity<File>()
.Property(e => e.FileType)
.HasConversion(new EnumToStringConverter<FileTypes>());
Solution 4
An alternative is to use a static class with string const fields instead of enums.
For example:
public class PocoEntity
{
public string Status { get; set; }
}
public static class PocoEntityStatus
{
public const string Ok = "ok";
public const string Failed = "failed";
}
For added validation on the database side you can add a check constraint to verify that the column is the expected value (you can do this when mapping to an enum as well, but since the property is just a string this helps ensure the consumer of your api set the value properly).
ALTER TABLE [PocoEntity]
ADD CONSTRAINT [CHK_PocoEntity_Status]
CHECK ([Status] in ('ok', 'failed'));
Solution 5
I had the same problem. I've come up with a solution, but I'm not completely happy with it.
My Person
class has a Gender
enum, and I use data annotations to map the string to the database and ignore the enum.
public class Person
{
public int PersonID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[Column("Gender")]
public string GenderString
{
get { return Gender.ToString(); }
private set { Gender = EnumExtensions.ParseEnum<Gender>(value); }
}
[NotMapped]
public Gender Gender { get; set; }
}
here is the extension method to get the correct enum from the string.
public class EnumExtensions
{
public static T ParseEnum<T>(string value)
{
return (T)Enum.Parse(typeof(T), value, true);
}
}
I wrote a blog post about this - http://nodogmablog.bryanhogan.net/2014/11/saving-enums-as-strings-with-entity-framework/
Sheldon Warkentin
Experienced Software Engineer with a demonstrated history of working in various industries. Strong engineering professional skilled in Java, C#, .NET, AWS, Google Cloud, Kubernetes, Terraform, Docker, Project planning, architecture, Eclipse RCP, Visual Studio, and more!
Updated on July 23, 2022Comments
-
Sheldon Warkentin almost 2 years
Is there a way to map a string column to an enum in an Entity Model?
I have done this in Hibernate, but can't figure it out in EMF.