Entity Frameworkでenumのビット演算
FlagsAttributeを適用したenum(「ビットフラグ列挙体」と言うんですかね)に対して、Entity Frameworkでビット演算してみました。
ビット演算というよりHasFlagsメソッドを使えるよね?ということを確認した感じです。
エンティティとDBコンテキスト
いつものごとくエンティティとDBコンテキストを作ります。
// フラグ [Flags] public enum ItemFlags { Apple = 0x01, // 0000 0001 Pineapple = 0x02, // 0000 0010 Pen = 0x04, // 0000 0100 } // エンティティ public class Item { public int Id { get; set; } // フラグを持つ public ItemFlags Flags { get; set; } } // DBコンテキスト public class AppDbContext : DbContext { public IDbSet<Item> Items { get; set; } // 色々省略 }
データも用意
dbo.Itemテーブルを作ってデータを用意しておきます。
-- こんな感じ select * from dbo.Item; /* Id Flags ----------- ----------- 1 5 -- 0000 0101 2 1 -- 0000 0001 3 6 -- 0000 0110 */
取得してみる
HasFlagメソッドを使って取得してみます。
// _connectionStringとか色々省略 using (var dbContext = new AppDbContext(_connectionString)) { var items = dbContext.Items .Where(item => item.Flags.HasFlag(ItemFlags.Pen)) .ToList(); foreach (var item in items) { Console.WriteLine($"Id = {item.Id}, Flags = {item.Flags}"); } } // 実行結果 /* Id = 1, Flags = Apple, Pen Id = 3, Flags = Pineapple, Pen */
クエリはこんな感じです。
SELECT [Extent1].[Id] AS [Id], [Extent1].[Flags] AS [Flags] FROM [dbo].[Item] AS [Extent1] WHERE (( CAST( [Extent1].[Flags] AS int)) & ( CAST( 4 AS int))) = 4
HasFlagを使わない場合も。
using (var dbContext = new AppDbContext(_connectionString)) { var items = dbContext.Items .Where(item => (item.Flags & ItemFlags.Pen) == ItemFlags.Pen) .ToList(); foreach (var item in items) { Console.WriteLine($"Id = {item.Id}, Flags = {item.Flags}"); } } // 実行結果 /* Id = 1, Flags = Apple, Pen Id = 3, Flags = Pineapple, Pen */
クエリもこんな感じ。
SELECT [Extent1].[Id] AS [Id], [Extent1].[Flags] AS [Flags] FROM [dbo].[Item] AS [Extent1] WHERE 4 = (( CAST( [Extent1].[Flags] AS int)) & (4))