枚举(Enum)是一种常用的类型,如用于表示状态、类型等参数。但目前它不会被官方地在ADO.NET Entity Framework中进行支持。本文介绍的是通过复杂类型(Complex Types)在ADO.NET Entity Framework 4中使用枚举。
这种方法需要使用POCO类,而不能使用Visual Studio自动生成的类。因为我们需要手动为复杂类型编写代码。
数据库脚本:

1 if exists (select 1
2 from sysobjects
3 where id = object_id('Account')
4 and type = 'U')
5 drop table Account
6 go
7
8 create table Account (
9 ID uniqueidentifier not null default NewSequentialID(),
10 UserName nvarchar(20) not null,
11 Password varchar(40) not null,
12 Email nvarchar(100) not null,
13 Role int not null,
14 constraint PK_ACCOUNT primary key (ID)
15 )
16
17 insert into Account (UserName ,Password,Email ,Role ) values ('Test1','Test1','test1',1)
18 insert into Account (UserName ,Password,Email ,Role ) values ('Test2','Test2','test2',1)
19 insert into Account (UserName ,Password,Email ,Role ) values ('Test3','Test3','test3',2)
2 from sysobjects
3 where id = object_id('Account')
4 and type = 'U')
5 drop table Account
6 go
7
8 create table Account (
9 ID uniqueidentifier not null default NewSequentialID(),
10 UserName nvarchar(20) not null,
11 Password varchar(40) not null,
12 Email nvarchar(100) not null,
13 Role int not null,
14 constraint PK_ACCOUNT primary key (ID)
15 )
16
17 insert into Account (UserName ,Password,Email ,Role ) values ('Test1','Test1','test1',1)
18 insert into Account (UserName ,Password,Email ,Role ) values ('Test2','Test2','test2',1)
19 insert into Account (UserName ,Password,Email ,Role ) values ('Test3','Test3','test3',2)
这是一个用于存放帐号信息的数据表,Role是个枚举类型,在数据库中用int类型。
我们按常规做法写一个用于表示Role的枚举类型
1 public enum AccountRoleEnum
2 {
3 Admin = 1,
4 User = 2
5 }
2 {
3 Admin = 1,
4 User = 2
5 }
然后写一个复杂类型用于在枚举类型和数据库的int类型之间做变换。复杂类型只有在ADO.NET Entity Framework 4中才有。

1 public partial class RoleWrapper
2 {
3 private AccountRoleEnum m_orderStatus;
4
5 public int Value
6 {
7 get { return (int)m_orderStatus; }
8 set { m_orderStatus = (AccountRoleEnum)value; }
9 }
10
11 public AccountRoleEnum EnumValue
12 {
13 get { return m_orderStatus; }
14 set { m_orderStatus = value; }
15 }
16
17 public static implicit operator RoleWrapper(AccountRoleEnum role)
18 {
19 return new RoleWrapper { EnumValue = role };
20 }
21
22 public static implicit operator AccountRoleEnum(RoleWrapper role)
23 {
24 if (role == null)
25 return AccountRoleEnum.User;
26 return role.EnumValue;
27 }
28 }
2 {
3 private AccountRoleEnum m_orderStatus;
4
5 public int Value
6 {
7 get { return (int)m_orderStatus; }
8 set { m_orderStatus = (AccountRoleEnum)value; }
9 }
10
11 public AccountRoleEnum EnumValue
12 {
13 get { return m_orderStatus; }
14 set { m_orderStatus = value; }
15 }
16
17 public static implicit operator RoleWrapper(AccountRoleEnum role)
18 {
19 return new RoleWrapper { EnumValue = role };
20 }
21
22 public static implicit operator AccountRoleEnum(RoleWrapper role)
23 {
24 if (role == null)
25 return AccountRoleEnum.User;
26 return role.EnumValue;
27 }
28 }
最后的2个方法用于隐式类型重载,也就是对类型进行变换。
然后我们写Account实体。

1 public class Account
2 {
3 public Guid ID { get; set; }
4
5 public string UserName { get; set; }
6
7 public string Password { get; set; }
8
9 public string Email { get; set; }
10
11 public RoleWrapper Role { get; set; }
12 }
2 {
3 public Guid ID { get; set; }
4
5 public string UserName { get; set; }
6
7 public string Password { get; set; }
8
9 public string Email { get; set; }
10
11 public RoleWrapper Role { get; set; }
12 }
和实体框架上下文。

1 public class EntitiesContext : ObjectContext
2 {
3 public EntitiesContext()
4 : base("name=Entities", "Entities")
5 {
6 _accounts = CreateObjectSet<Account>();
7 }
8
9 public ObjectSet<Account> Accounts
10 {
11 get
12 {
13 return _accounts;
14 }
15 }
16 private ObjectSet<Account> _accounts;
17 }
2 {
3 public EntitiesContext()
4 : base("name=Entities", "Entities")
5 {
6 _accounts = CreateObjectSet<Account>();
7 }
8
9 public ObjectSet<Account> Accounts
10 {
11 get
12 {
13 return _accounts;
14 }
15 }
16 private ObjectSet<Account> _accounts;
17 }
这样,主要的工作就已经完成了,在比较时可以使用
1 account.Role == AccountRoleEnum.Admin
但是在涉及到数据库的查询时,这样的写法是会报错的,只能使用
1 EntitiesContext db = new EntitiesContext();
2 db.Accounts.Where(c => c.Role.Value == (int)AccountRoleEnum.Admin);
2 db.Accounts.Where(c => c.Role.Value == (int)AccountRoleEnum.Admin);
参考文章
http://blogs.msdn.com/adonet/archive/2009/05/21/poco-in-the-entity-framework-part-1-the-experience.aspx
http://blogs.msdn.com/alexj/archive/2009/06/05/tip-23-how-to-fake-enums-in-ef-4.aspx
分类:
.NET Framework
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述