如何在Entity Framework中使用枚举?

53

如何在Entity Framework中最好地使用枚举?

备注:我正在使用EF 3和Firebird。


这个也可以工作 链接 - Korayem
5个回答

27

1
@Michel,是的,你可以在EF 5中完成它 - Craig Stuntz

20

更新:
Entity Framework现在本地支持枚举。

原文:
这是EF中令人烦恼的事情之一。仍未支持它!

或者,您可以执行类似以下操作:

public MyEnum MyEnumProperty  
{  
  get { return (MyEnum) InnerEnumProperty; }  
  set { InnerEnumProperty = (int) value; }  
}

但这让我感觉很不好。


2
虽然这个字段有点脏,但还有另一个问题,如果你在查询中使用这个字段,EF会抱怨。为了解决这个问题,我创建了这个包装器:http://landman-code.blogspot.com/2010/08/adding-support-for-enum-properties-on.html,它允许你在实体的外部保持干净,不涉及EF的细节。 - Davy Landman

11

6

我经常在数据库中使用表格(默认值)

CREATE TABLE [dbo].[CommunicationPreferences]
(
    [ID] smallint NOT NULL,
    [SystemName] nvarchar(50) NOT NULL,
    [Description] nvarchar(200) NOT NULL,
)

我从数据库中获取我的EF4实体。

注意:我不使用视图、SPROCS或SQL函数,也不使用复杂的EF类型,只是直接将表映射到实体。然后扩展我的实体部分类以添加其他功能,以保持DRY(Don't Repeat Yourself)原则。

对于枚举,我有一个简单的T4模板,我手动提供一个表列表(如上所述),每当我从数据库更新EF模型时(或者在需要时),.tt文件就会被触发,它获取数据并构建枚举,例如:

/// <summary> 
/// Enums For The dbo Schema
/// </summary>
public enum CommunicationPreferencesList : short
{
    /// <summary> 
    /// HTML Emails
    /// </summary>
    [EnumTextValue(@"HTML Emails")]
    HTMLEmail = 1,

    /// <summary> 
    /// Plain Text Emails
    /// </summary>
    [EnumTextValue(@"Plain Text Emails")]
    PlainEmail = 2,

    /// <summary> 
    /// Mobile Telephone
    /// </summary>
    [EnumTextValue(@"Mobile Telephone")]
    Mobile = 3,

    /// <summary> 
    /// Landline Telephone
    /// </summary>
    [EnumTextValue(@"Landline Telephone")]
    Landline = 4,

    /// <summary> 
    /// SMS
    /// </summary>
    [EnumTextValue(@"SMS")]
    SMS = 5,

}

当我处理一些实体上的外键ID列/属性时,比如:

Users.CommunicationPreferenceID

我只是将ID或枚举类型用于比较。例如:

CommunicationPreferencesList usersPreference = (CommunicationPreferencesList)currentUser.CommunicationPreferenceID;

if(usersPreference == CommunicationPreferencesList.SMS)
{
//send SMS
}
else if(usersPreference == CommunicationPreferencesList.Mobile)
{
//ring the phone
}

我有一些简单的辅助工具,例如从枚举实例中获取EnumTextValue。

string chosenMethod = EntityHelper.GetEnumTextValue(CommunicationPreferencesList.Mobile);

 => "Mobile Telephone"

我发现这个方法简单、无麻烦、透明易用,对我来说很有效,我很满意。我不认为有必要完全隐藏数据库/实体中的数字值,并且我很愿意将其中一个值转换,从而得到相当干净可读的代码,同时从数据库中的[Description]字段生成的EnumTextValue是一个很好的额外附加值。

2
有趣的想法。但是可能存在潜在的数据完整性问题。如果您删除/编辑现有的数据库条目并重新生成T4模板,那么使用已删除枚举的代码将无法编译。更糟糕的是,如果有人意外删除了数据库条目,然后重新安装它,键可能会不同。然后,保存到数据库中的任何枚举值都将与枚举中的错误项目相关联(或根本没有匹配值)。也许反过来做-将枚举持久化到数据库中可能会更少出错? - Appetere
也许吧,但就我个人而言从未遇到过任何问题... 1. 我不在 PK 列上使用 identity,因此自增 ID 不可能与之不匹配 2. 持久性的方式并不重要,重要的是不能只改变其中一个,或者必须有一种机制来确保它们保持同步,例如我使用自动默认值 SQL 脚本在每次应用程序/数据库发布时设置查找表数据(如果某些原因导致其更改) 4. 我们希望使用已删除条目的代码无法编译。这就是整个意图! - MemeDeveloper

0

我曾经遇到过类似的问题,并通过使用部分类机制编写实体扩展来解决它。我只是添加了一个属性,该属性在实体中执行DB字段的转换,对于我们的情况只是一个整数。

唯一需要注意的是要添加一个忽略序列化属性,例如在与WCF结合使用时。


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