やりたいこと
Entity Frameworkのデータベースファーストを使用する場合、モデルクラスの各プロパティの型は、データベースの型によって勝手に決められます。「XXステータス」のように、取りうる値が決まっているケースでは、.NETアプリケーション内でできればEnumを使用したいところです。しかし、単純にモデルクラスを生成しただけでは、Enumを使うようにしてくれません。今回はEnumを使うように設定する方法を解説します。
環境
- Visual Studio 2019 16.1.4
- Entity Framework 6.2.0
- .NET Framework 4.7.2
対象のテーブル
以下のようなテーブルを準備します。
CREATE TABLE [dbo].[Table] ( [Id] INT NOT NULL, [Status] SMALLINT NOT NULL );
とりあえずモデルクラスを生成する
Visual Studioで「ADO.NET Entity Data Model」を新たに作成します。そして上記のテーブルをモデルとして生成します。すると以下のようなモデルが生成されます。
「Status」のプロパティを参照すると、型が「Int16」にマッピングされているのがわかります。次にこの「Status」をEnumで取り扱えるようにします。
Enumを使えるようにする
まずedmxファイルを開いて、対象のプロパティを右クリックします。そして「Enumに変換」を押下します。
新たに列挙型を作成する場合
新たに列挙型を作成する場合は、「列挙型の追加」画面で追加する列挙型の名前、基になる型、値のリストを設定して「OK」ボタンを押下します。
すると、設定した通りのEnumが新たに生成されます。生成する先は、以下の通りです。
なお設定したのにEnumが生成されいていない場合は、再度ビルドするか、edmxを右クリックして「カスタムツールの実行」を選択してください。
生成されたEnumは以下のようになります。
//------------------------------------------------------------------------------ // <auto-generated> // このコードはテンプレートから生成されました。 // // このファイルを手動で変更すると、アプリケーションで予期しない動作が発生する可能性があります。 // このファイルに対する手動の変更は、コードが再生成されると上書きされます。 // </auto-generated> //------------------------------------------------------------------------------ namespace EF_Enum.DataAccess { using System; public enum Status : short { Default = 0, Executing = 1, Done = 2 } }
既存の列挙型を使用する場合
既に列挙型の定義ができている場合は、その型をモデルクラスで使用することもできます。以下のEnumをEntity Frameworkのモデルクラスから使用してみます。
namespace EF_Enum { public enum Status : short { Default = 0, Executing = 1, Done = 2 } }
前述の手順同様、「列挙型の追加」画面まで進みます。「名前」に任意の名前を入れて、「外部の型の参照」に存在するEnumの型名を設定します。型名は名前空間を含む完全修飾名で指定することに注意してください。
モデルクラスの再生成を行うと、モデルクラスが以下のように書き換わります。
//------------------------------------------------------------------------------ // <auto-generated> // このコードはテンプレートから生成されました。 // // このファイルを手動で変更すると、アプリケーションで予期しない動作が発生する可能性があります。 // このファイルに対する手動の変更は、コードが再生成されると上書きされます。 // </auto-generated> //------------------------------------------------------------------------------ namespace EF_Enum.DataAccess { using System; using System.Collections.Generic; public partial class Table { public int Id { get; set; } public EF_Enum.Status Status { get; set; } } }
確かに、指定したEnumが使われるようになっていることがわかります。
何が嬉しいのか
特にWhere句を組み立てる際、以下のように型を利用した実装ができるようになります。実装から「妙な数字」が消え去るので、可読性が大きく向上します。
using (EFEnumTestDbContext context = new EFEnumTestDbContext()) { var count = context.Tables.Where(r => r.Status == Status.Done).Count(); }