Entity Framework Plus を使ってタイプセーフに一括更新を行う

Entity Framework Core を使っていて、 エンティティをまとめて更新したい場面は結構あるが、 タイプセーフかつ効率的に更新する手段は、 今のところ標準で提供されていない。

ExecuteSqlCommand を使って直接 SQL を発行すればいいんだけど、 テストではInMemoryプロバイダーを使用しているので、 一括更新だけ違うやり方でテストしなければいけなくなるのが面倒。

そこで Entity Framework Plus を使ってみることにした。 Entity Framework と Entity Framework Core の機能を拡張できるライブラリ。

entityframework-plus.net

Entity Framework Core 用のパッケージを使う。

www.nuget.org

IQueryable に拡張メソッドが追加されるので、 非同期に一括で更新したい場合は UpdateAsync を使えばいい。

var publishedAt = DateTimeOffset.UtcNow;

var query = from e in context.Entries
            join b in context.Blogs on e.BlogId equals b.Id
            where e.TenantId == tenantId
            where b.UserId == userId
            where e.IsDraft
            select e;

await query.UpdateAsync(e => new Entry()
{
    IsDraft = false,
    PublishedAt = publishedAt,
});

普通に使うぶんにはこれでOK。 ただ注意点があって、テストで InMemory プロバイダーを使っていると

UpdateAsync results in Unable to cast object of type 'Microsoft.EntityFrameworkCore.Query.Internal.InMemoryQueryContextFactory'

という例外が発生してしまう。 その場合は

BatchUpdateManager.InMemoryDbContextFactory = () => new ApplicationDbContext(options);

という風に、Entity Framework Plus に DbContext を取得するためのデリゲートを登録しておくことで回避可能。

中華そばつけ麺 永福

天神南駅近くにある『中華そばつけ麺 永福』に行ってみた。 ここは中華そばの店なんだけど、同じく中華そばの『郷家』の真向かいに出店していて、 かなり挑戦的。長住から移転してきたらしい。なぜこの場所を選んだんだ…。

注文したのは中華そば。 鶏・豚・魚介のハイブリッドスープは、濃いめでパンチが効いていた。 これが東京風か。 ツルッとした中太麺も美味だった。 替え玉しておけばよかったな。

関連ランキング:ラーメン | 天神南駅西鉄福岡駅(天神)渡辺通駅

『からかい上手の(元)高木さん』を読んだ

からかい上手の高木さん』のスピンオフ。西片君と、西片君と結婚した(元)高木さんと、娘のちーちゃんの日常のお話。 本編で西片君と高木さんが結婚したと思われるシーンはあったので、二人が結婚するのは正史と言える。

ちーちゃんの性格は明らかに父親似だな。そんなちーちゃんが(元)高木さんと勝負するわけだが、父親似の娘は(元)高木さんには勝てない。あと、大人になっても西片君は勝てないようで、変わってなくて一安心。

(元)高木さんとちーちゃんがタッグを組むこともあれば、西片君とちーちゃんが組むこともあり、本編とはまた違った形の勝負が見れて、これはこれで面白いと思う。

Xamarin.iOS でキーチェーンを有効にする

Xamarin.iOS でアプリを作っていて、キーチェーンを使いたくなったときにいつも嵌るので、有効化の方法をメモしておく。

Visual Studio for Mac でプロジェクトを開いている状態で、まずは Entitlements.plist を開き、 「キーチェーンを有効にする」にチェックを入れる。 キーチェーングループの一覧には、アプリのバンドル識別子が含まれているはず。

f:id:griefworker:20180125225427p:plain

Xamarion.iOS プロジェクトのオプションを開き、iOS バンドル署名を選択。 カスタムエンタイトルメントが空欄になっていた場合は、 プロジェクト内の Entitlements.plist を指定する。

f:id:griefworker:20180125225614p:plain

以上。 あとは Security フレームワークを使って、キーチェーンにアクセスするコードを書けばいい。

EntityFrameworkCore で SQL Server の IDENTITY プロパティを使うときの注意点

EntityFrameworkCoreのバージョンは v2.0.1。

例えば次のようなテーブルがあるとする。

create table Entry (
    Id bigint identity(1,1) not null,
    Title nvarchar(100) not null,
    Body nvarchar(max) null,

  constraint pk_Entry primary key clustered 
  (
      Id asc
  )
)

このテーブルにマッピングする C# のクラスはこんな感じ。

public class Entry
{
    public long Id { get; set; }
    public string Title { get; set; }
    public string Body { get; set; }
}

EntityFrameworkCore の Fluent API で、クラスとテーブルをマッピングする。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Entry>()
        .Property(e => e.Id)
        .UseSqlServerIdentityColumn();
    modelBuilder.Entity<Entry>()
        .Property(e => e.Title)
        .IsRequired();
    modelBuilder.Entity<Entry>()
        .Property(e => e.Body);
}

これでいいと思っていたけど、実際に動かしてみるとダメだった。 UPDATE 時に Id を更新しようとしてしまい、SqlException 発生。死亡。

Id を更新しないように設定してあげないといけなかった。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Entry>()
        .Property(e => e.Id)
        .UseSqlServerIdentityColumn()
        .Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore; // Id 列を更新しないようにする
    modelBuilder.Entity<Entry>()
        .Property(e => e.Title)
        .IsRequired();
    modelBuilder.Entity<Entry>()
        .Property(e => e.Body);
}

最初、ドキュメントを探しても解決方法を見つけることができず途方に暮れたが、 GitHub リポジトリに登録されているイシューを見つけることができた。 嵌ったときはイシューも見る。これ大事。

『星野、目をつぶって。(9)』を読んだ

小早川はバイトという新しい世界に足を踏み出し、 加納も松方と和解するために漫画のことを理解しようと積極的に行動し、 そんな加納の影響を受けて松方も歩み寄りの姿勢を見せたりと、 皆変わるために前に進み始めはじめた。 ただ一人、星野を除いて。星野だけは、小早川との関係は隠したままだし、素顔も隠したままだしと、いっこうに変われずにいる。 小早川はもう自分で自分を肯定できるようになったし、次は星野にフォーカスが移りそう。

あと新キャラの小宮はフリーダム過ぎて好きにはなれないな。小早川と星野にちょっかいを出すためだけに登場したのかと勘ぐってしまう。周りにハブられていると分かっておきながら、自分を変えずに本能のまま行動し続けるのは、なんだかなぁって思った。

『かぐや様は告らせたい(8)』を読んだ

8巻はひさしぶりに全部日常回で、安定した面白さだった。特に生徒会新メンバーの伊井野ミコが良い。前期メンバーには、会長やかぐやに辛辣なツッコミを入れる役割が不在だったので、彼女の存在は貴重。会長に「くずめ」なんて言えるのはミコだけだろう。良いアクセントになっている。

あと、かぐやと早坂のコンビも面白い。 早坂にからかわれるかぐやは、生徒会メンバーの前とは違った表情を見せて良い。早坂の方も、かぐやに振り回されて、キャラに綻びがでるところが面白い。主人が無自覚に恥をさらすのに耐えるところとか特に。この2人セットでの出番がもっと見たい。