Entity Framework 枚举和字符串的关联

3
我想使用这篇文章中的方法,为我的枚举类型实现更友好的 ToString() 输出。我想知道如何在Entity Framework的自动生成的枚举代码中实现它?我需要修改代码生成模板吗(如果需要,能否请有经验的人给我一些指导,因为模板相当复杂),还是有其他替代方法?
谢谢!

“auto generated Enum codes” 是什么意思?您是在说使用“model/DB first”方法吗? - Floremin
这涵盖了EF数据库优先方法的枚举支持:https://dev59.com/3WMm5IYBdhLWcg3wRdbe 还要查看其他答案以获取附加链接。 - Floremin
@Floremin:是的,我正在使用模型优先。因此,我的整个模型都是通过设计师完成的,包括我的枚举类型。包含枚举声明的类因此是由EF的T4自动生成的。现在的问题是,由于枚举类型的命名受限,我的枚举在ASP.net网站中很难使用,这正是我链接的文章中描述的场景,作者使用DescriptionAttribute(反射)来解决这个问题。我认为在EF中这是无法实现的,除非对T4模板进行广泛修改,因为代码是自动生成的。 - thankyoussd
2个回答

6
您可以在EF模型中使用自己的枚举类型,而不是在模型设计器中创建新的枚举。以下是方法:
在模型设计器中,在表面上右键单击,然后选择:
添加新项 -> 枚举类型...
在对话框中,只需设置复选框:
引用外部类型
并输入您的类型:namespace.MyEnum
然后,在表中创建列以使用此类型。
由于您可能会修改现有的模型,请确保模型中的枚举类型与您代码中的(外部)枚举类型之间没有混淆。最好的方法是删除先前在模型中创建的枚举类型,并调整列以使用来自您代码的关联枚举类型。
现在,您可以像计划的那样声明具有描述属性的枚举类型。

非常感谢您指出我一直忽略的外部引用选项。我尝试了一下,似乎完美地解决了问题。这种方式使EF的设计师仍然可以访问新的枚举类型,这意味着它们可以轻松地用作实体的属性类型(无需在数据库上手动设置任何内容)。我非常满意。 - thankyoussd

5

Enums不需要使用任何变通方法,它们在最新的Entity Framework中得到了支持。

为了使您的枚举对您的网站更加友好,您可以使用属性。这是一个示例属性:

public class EnumDescription : Attribute
{
    public string Text { get; private set; }

    public EnumDescription(string text)
    {
        this.Text = text;
    }
}

使用属性标记您的枚举:

public enum DaylightSavingTime
{
    [EnumDescription("Detect automatically")]
    Auto = 0,
    [EnumDescription("DST always on")]
    AlwaysOn = 1,
    [EnumDescription("DST always off")]
    AlwaysOff = 2
}

添加扩展以启用ToDescription()方法:

public static class EnumExtensions
{
    public static string ToDescription(this Enum enumeration)
    {
        Type type = enumeration.GetType();
        MemberInfo[] memInfo = type.GetMember(enumeration.ToString());

        if (null != memInfo && memInfo.Length > 0)
        {
            object[] attrs = memInfo[0].GetCustomAttributes(typeof(EnumDescription), false);
            if (null != attrs && attrs.Length > 0)
                return ((EnumDescription)attrs[0]).Text;
        }

        return enumeration.ToString();
    }
}

使用方法:

var blabla = DaylightSavingTime.Auto;
Console.WriteLine(blabla.ToDescription());

输出:

自动检测


是的,我知道它被支持并且我已经在使用它了。我的问题是由于枚举命名限制(例如,成员只能被命名为NewYork,而不能是New York),我的枚举类型在我的asp.net网站中很难使用(正如我链接的那篇文章所描述的)。 - thankyoussd
@user3144721,我已经更新了答案(如果你喜欢,请点赞) - Roman Pushkin
感谢您的回复,尽管我在原帖中已经链接了描述如何使用属性来设置友好枚举名称的文章。我的问题是,使用EF的模型设计器时,枚举声明是自动生成的且不可编辑的(任何对自动生成的类文件的修改都会在更新模型时被覆盖),因此我无法添加属性。如果我想在设计时完成这个任务,Floremin的方法(在外部编写枚举)似乎是我的唯一选择。 - thankyoussd
1
我也意识到你提出的扩展方法方法是一个好主意(而不是使用我要遵循的文章中显示的常规静态方法)。现在我将在外部定义的枚举类型中使用扩展方法。两全其美。谢谢! - thankyoussd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接