如何将数据库中的枚举保存为字符串

时间:2015-09-12 18:37:06

标签: c# .net entity-framework c#-4.0

这是我的模型类,我们有一个类型,可以是Zombie或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
}

目前它正在Int

中保存数据

enter image description here

我想将数据保存为Human和Zombie,而不是int

7 个答案:

答案 0 :(得分:21)

您可以将枚举作为字符串保存到数据库中,我同意dotctor这不是最好的主意,但如果需要,您需要进行一些更改。

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; }
}  

将此扩展程序类添加到项目中。

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

完整详情在此处 - http://NoDogmaBlog.bryanhogan.net/2014/11/saving-enums-as-strings-with-entity-framework/

答案 1 :(得分:6)

据我所知,我遇到了这个问题,说实话,我不知道为什么MS没有添加这个功能(NH可以像往常一样......)。

任何方式,我通常做的是使用const字符串类,如:

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;
    }

}

缺点 - 尽可能简单。

下行 - 您放松了类型检查(尽管可以通过编程方式强制执行)。

所以这一次我试着想出更雄心勃勃的事情。所以我采用了Brian描述的概念(当例如在域中广泛使用给定的枚举时,它有一些缺点)。好吧..我得到了以下工作:

用于存储值的基本组件类:

[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();
    }
}

......这基本上就足够了......除了EF不支持通用类型......

这意味着每个枚举都必须包含......

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();
    }
}

它为您提供了一些易于生成的锅炉板,例如使用T4模板。

最终结束了使用:

public class CalendarEntry : Entity
{

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

}

但是由于你有隐式转换,所以类声明是唯一需要知道帮助类型的。

答案 2 :(得分:4)

将它们存储为字符串不是一个好主意,但您可以使用ef enum to lookup为您的枚举创建查找表,并且它非常易于使用。

答案 3 :(得分:1)

我认为,将它们存储为ssh会更有用,因为您可以非常轻松地将int从DB转换为int

但如果你想要的话,有两种方法。您可以将enum(或Type.Zombie.ToString()分别)保存到数据库(将是“Zombie”),或者您可以获取正在使用的Type.Human.ToString()的值并将其保存到D B。如何获得描述的描述here。 - 在这种情况下它也会是“Zombie”,但它可能是你在DescriptionAttribute中写的其他内容。

如果您使用Description(),则可以使用Enum.Parse来获取ToString的实例。如果您使用描述,那就不那么容易了。

答案 4 :(得分:1)

将枚举显式转换为字符串将使您的代码混乱,并且您必须继续解析值。查找表也是如此。只需在您的枚举字段中添加TypeName属性,然后将nvarchar指定为varchar(对于SQL)或public class User { public int ID { get; set; } public string Name { get; set; } [Column(TypeName = "nvarchar(20)")] public Type Type { get; set; } public List<Wepon> WeposInList { get; set; } } (对于postgres)即可。像魅力一样为我工作。 以您的情况为例:

.class

您可以在官方文档here

中了解更多信息

答案 5 :(得分:1)

关于 Martin's answer,Entity Framework Core 有一个 pre-defined converter 用于枚举到字符串。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<User>()
        .Property(e => e.Type)
        .HasConversion<string>();
}

同样可以通过以下方式实现:

public class User
{
    public int ID { get; set; }

    public string Name { get; set; }

    [Column(TypeName = "nvarchar(24)")]
    public Type Type { get; set; }

    public List<Weapon> WeaponsInList { get; set; }
}

答案 6 :(得分:0)

modelBuilder.Entity<DataSet>().Property(d => d.SemanticType).HasConversion(new EnumToStringConverter<DataSetSemanticType>());