
在 entityframework core 中的實體是不直接支持枚舉類型的操作,這讓我們在開發過程中帶來不少的麻煩,下面總結一下在 ef core 中使用枚舉的方法.
例如下面的msginfo實體,對應著資料庫表msginfo,其中欄位sendstate發送狀態在業務邏輯上有發送成功和發送失敗兩種枚舉狀態。但 ef 把它生成了 int 類型,而不是枚舉,當然也不能修改成枚舉,這樣會導致 ef 寫入和讀取數據異常。
原來的實體
public partial class MsgInfo
{
public string Id { get; set; }
public string UserAddress { get; set; }
public string Content { get; set; }
public int SendState { get; set; }
}
这里新增一个字段SendStateEnum设置为枚举类型,并使用 [NotMapped] 为不映射到数据库,为了防止输出 HTTP 时被序列化,也可以添加 [Newtonsoft.Json.JsonIgnore] 标记
需添加 nuget 包 newtonsoft.json
修改完的實體代碼如下
修改實體
public partial class MsgInfo
{
public string Id { get; set; }
public string UserAddress { get; set; }
public string Content { get; set; }
public int SendState { get; set; }
[NotMapped]
[Newtonsoft.Json.JsonIgnore]
public SendStateEnum SendStateEnum
{
get
{
switch (SendState)
{
case (int)SendStateEnum.Fail:
return SendStateEnum.Fail;
case (int)SendStateEnum.Success:
return SendStateEnum.Success;
default:
return SendStateEnum.UnKnow;
}
}
set
{
SendState = (int)value;
}
}
}
public enum SendStateEnum
{
Success = 1,
Fail = 2,
UnKnow =3
}
添加了sendstateenum欄位後,以後使用 ef core 操作或者讀取sendstateenum 代替了 sendstate 欄位(註:站長實測與原文有出入,如下面的代碼(原文代碼)貌似應該使用 sendstate 進行 ef core 的操作,如有不同意見請留言指正。)
using (var context = new FrameworkDbContext())
{
var result = context.MsgInfo.Where(m => m.SendStateEnum == SendStateEnum.Success);
}
当然,为了防止原来的 SendState 字段被使用,可以添加标记 [Obsolete] 提醒用户该字段 SendState 已过时。
修改後的最終實體代碼如下
public partial class MsgInfo
{
public string Id { get; set; }
public string UserAddress { get; set; }
public string Content { get; set; }
[Obsolete]
public int SendState { get; set; }
[NotMapped]
[Newtonsoft.Json.JsonIgnore]
public SendStateEnum SendStateEnum
{
get
{
switch (SendState)
{
case (int)SendStateEnum.Fail:
return SendStateEnum.Fail;
case (int)SendStateEnum.Success:
return SendStateEnum.Success;
default:
return SendStateEnum.UnKnow;
}
}
set
{
SendState = (int)value;
}
}
}
public enum SendStateEnum
{
Success = 1,
Fail = 2,
UnKnow =3
}