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

b1uwtaje  于 2022-12-20  发布在  .NET
关注(0)|答案(8)|浏览(184)

这是我的模型类,我们有一个类型,它可以是僵尸或人类。

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

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

当前,它正在将数据保存在Int.

我想将数据保存为人类和僵尸,而不是使用int。

rekjcdws

rekjcdws1#

在实体框架核心中,您可以指定内置转换:

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

更多详情here

iyr7buue

iyr7buue2#

您可以将枚举作为字符串保存到DB中,我同意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/

kmpatx3s

kmpatx3s3#

据我所知,我有这个问题,老实说,我不知道为什么MS没有添加这个功能(NH可以像往常一样做...)。
无论如何,我通常使用的是常量字符串类,如下所示:

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

}

但是,由于您已经有了隐式转换,因此类声明是唯一知道帮助器类型的声明。

v440hwme

v440hwme4#

对于Martin的回答,EntityFrameworkCore有一个预定义的从枚举到字符串的转换器。

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

57hvy0tb5#

显式的枚举到字符串的转换会使你的代码混乱,你必须不断地解析值。查找表也是如此。只需添加[Column]属性到你的枚举字段,并指定TypeNamenvarchar(用于SQL)或varchar(用于postgres)。对我来说就像一个魔咒。在你的例子中,例如:

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

    }

您可以在此处的官方文档中阅读更多信息

js5cn81o

js5cn81o6#

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

bejyjqdl

bejyjqdl7#

我认为,将它们存储为int要有用得多,因为您可以很容易地将int从DB转换为enum
但是如果这是您想要的,有两种方法:您可以保存Type.Zombie.ToString()(或Type.Human.ToString())到数据库(这将是“僵尸”),或者你可以获得DescriptionAttribute的值,你正在使用,并保存到数据库。如何获得描述描述描述here。-它也将是“僵尸”在这种情况下,但它可能是您在Description()中编写的任何其他内容。
如果你使用ToString,你可以使用Enum.Parse来取回enum的示例,如果你使用描述,就不那么容易了。

htzpubme

htzpubme8#

您可以使用Newtonsoft属性

[JsonConverter(typeof(StringEnumConverter))]
public enum MyEnum
{
}

相关问题