将entity framework中的字符串列映射到枚举

有没有办法将字符串列映射到实体模型中的枚举?

我在Hibernate中做过这个,但是无法在EMF中弄明白。

这很难看,但是为了将枚举映射到字符串,我发现了这样的东西:

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是枚举器类型,Status是枚举器,StatusString是它的字符串版本。

可能是一个更好的版本。

OrderStateIdentifier字段用于JSON序列化和数据库字段,而OrderState仅在代码中用于方便。

  public string OrderStateIdentifier { get { return OrderState.ToString(); } set { OrderState = value.ToEnum(); } } [NotMapped] [JsonIgnore] public OrderState OrderState { get; set; } public static class EnumHelper { ///  /// Converts string to enum value (opposite to Enum.ToString()). ///  /// Type of the enum to convert the string into. /// string to convert to enum value. public static T ToEnum(this string s) where T: struct { T newValue; return Enum.TryParse(s, out newValue) ? newValue : default(T); } } 

我认为还有另一个解决方案。

我们最近在项目中所做的是使用扩展方法。

我写了两个,一个用于Enum,一个用于实体,但这里是示例:

 namespace Foo.Enums { [DataContract] public enum EAccountStatus { [DataMember] Online, [DataMember] Offline, [DataMember] Pending } 

…枚举本身,现在包含静态类的扩展方法:

  public static class AccountStatusExtensionMethods { ///  /// Returns the Type as enumeration for the db entity ///  /// Entity for which to check the type /// enum that represents the type public static EAccountStatus GetAccountStatus(this Account entity) { if (entity.AccountStatus.Equals(EAccountStatus.Offline)) { return EAccountStatus.Offline; } else if (entity.AccountStatus.Equals(EAccountStatus.Online)) { return EAccountStatus.Online; } else if (entity.AccountStatus.Equals(EAccountStatus.Pending)) { return EAccountStatus.Pending; } throw new System.Data.Entity.Validation.DbEntityValidationException( "Unrecognized AccountStatus was set, this is FATAL!"); } 

…实体类型的扩展方法,以及缩短输入的便捷方法:

  ///  /// Gets the String representation for this enums choosen ///  /// Instance of the enum chosen /// Name of the chosen enum in String representation public static String GetName(this EAccountStatus e) { return Enum.GetName(typeof(EAccountStatus), e); } } } 

……最后用法:

 // to set always the same, mappable strings: db.AccountSet.Single(m => m.Id == 1).Status = EAccountStatus.Online.GetName(); // to get the enum from the actual Entity you see: EAccountStatus actualStatus = db.AccountSet.Single(m => m.Id == 1).GetAccountStatus(); 

现在,你只需要“使用Foo.Enums;” 你可以在实体和枚举上调用方法。 更好的是,在某些实体的包装器中,您还可以在不同类型之间进行无缝编组,这些类型代表大项目中的相同事物。

唯一值得注意的是,在将Linq表达式传递给Linq之前,有时必须执行扩展方法。 这里的问题是Linq无法在自己的上下文中执行扩展方法…

也许只是一种替代方案,但我们已经这样做了,因为它为您提供了如何为实体获取东西的极大灵活性。 您可以轻松编写扩展程序以在ShoppingCart中接收帐户实际产品…

问候,Kjellski

另一种方法是使用带有字符串const字段而不是枚举的静态类。

例如:

 public class PocoEntity { public string Status { get; set; } } public static class PocoEntityStatus { public const string Ok = "ok"; public const string Failed = "failed"; } 

为了在数据库端添加validation,您可以添加一个检查约束来validation该列是否为期望值(您也可以在映射到枚举时执行此操作,但由于该属性只是一个字符串,这有助于确保您的消费者api正确设置值)。

 ALTER TABLE [PocoEntity] ADD CONSTRAINT [CHK_PocoEntity_Status] CHECK ([Status] in ('ok', 'failed')); 

它位于EF7的路线图上: https : //github.com/aspnet/EntityFramework/issues/242

你可能想投票支持它: http : //data.uservoice.com/forums/72025-entity-framework-feature-suggestions/suggestions/2639292-simple-type-mapping-or-mapped-type-conversion-sup

我有同样的问题。 我想出了一个解决方案,但我并不完全满意。

我的Person类有一个Gender枚举,我使用数据注释将字符串映射到数据库并忽略枚举。

 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(value); } } [NotMapped] public Gender Gender { get; set; } } 

这是从字符串中获取正确枚举的扩展方法。

 public class EnumExtensions { public static T ParseEnum(string value) { return (T)Enum.Parse(typeof(T), value, true); } } 

我写了一篇关于此的博客文章 – http://nodogmablog.bryanhogan.net/2014/11/saving-enums-as-strings-with-entity-framework/

如果要将枚举值映射到另一个对应字符串(例如缩写),可以使用以下方法:

 public class MinhaClasse { public string CodTipoCampo { get; set; } [NotMapped] public TipoDado TipoCampo { get => DictValorTipoDado.SingleOrDefault(e => e.Value == CodTipoCampo).Key; set => CodTipoCampo = DictValorTipoDado[value]; } private Dictionary DictValorTipoDado = new Dictionary() { { TipoDado.Texto, "T" }, { TipoDado.Numerico, "N" }, { TipoDado.Data, "D" } }; public enum TipoDado { Texto, Numero, Data } }