
EntityFramework Core ではエンティティが列挙型を直接サポートしていないため、開発時に多くの不便が生じます。以下に、ef core で列挙型を使用する方法をまとめます。
例えば、以下の MsgInfo エンティティはデータベーステーブル MsgInfo に対応しており、フィールド SendState(送信状態)はビジネスロジック上、送信成功と送信失敗の2つの列挙状態を持ちます。しかし 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 での操作や読み取り時に SendState フィールドの代わりに SendStateEnum を使用します(注:サイト管理者が実際に試したところ、原文とは異なります。以下のコード(原文のコード)は ef core の操作に SendState を使用すべきと思われます。異論があればコメントで指摘してください。)
using (var context = new FrameworkDbContext())
{
var result = context.MsgInfo.Where(m => m.SendStateEnum == SendStateEnum.Success);
}
もちろん、元の SendState フィールドが使用されないようにするため、[Obsolete] 属性を追加して、このフィールドが非推奨であることをユーザーに知らせることができます。
修正後の最終エンティティコード
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
}