Azure 上の .NET Core では DbSet の Join ができない

ひどくピンポイントかつ3時間ほどハマってしまったので、メモ書き的に残しておく。

環境は、

  • ASP.NET Core
  • .NET Core 1.1
  • EF Core を利用

ASP.NET Core で Web API を作っていて、ローカルの .NET Core で LINQ の Join が動いていたのだが、いざ Azure にアップロードして動作させると、Join 部分がうまくいかなくて意味不明なエラーを返した。

var cnt1 = (
        from ti in _context.TicketView
        join st in _context.Status on ti.Status_Id equals st.Id
        where ti.ProjectId == project.Id &&
                ti.Tracker_Id == tr.Id &&
                st.IsClosed == false
        select ti.Id
    ).Count();

とあるところで、こんな風に TicketView と Statues テーブルを JOIN させた。何をやりたかったかというと、Statues テーブルの IsClosed フラグを見て、その数をカウントしたかったのだ。これを、ローカル PC の ASP.NET Core で動作させると、するすると動いたので、そのまま Azure に乗せてみると…

テーブル構造が違っているからマイグレーションしろ、

というお達しが来る。最初は、エラーの意味が解らなくて四苦八苦したのだが、少しずつ障害を絞り込んでいくとここの JOIN 部分に至った。この JOIN を消してしまって、var cnt1 = 0 とすると動作することが分かったので、あれこれやって、

var status = _context.Status.OrderBy(x => x.Position).ToList();
var ticketviews = _context.TicketView.Where(x => x.ProjectId == project.Id).ToList();

var cnt1 = (from ti in ticketviews
            join st in status on ti.Status_Id equals st.Id 
            where ti.ProjectId == project.Id &&
                    ti.Tracker_Id == tr.Id &&
                    st.IsClosed == false
            select ti.Id).Count();

な風に、一度 List に取り込んでから JOIN するとうまく動くようになった。

LINQ を使ってジェネリックの List 同士を Join させる分には大丈夫と解っているのだが、_context.Status のほう(DbSet<Status> などで DI されている)の Join の動作が不明である。もともと、ローカル PC で DbSet 同士の Join ができちゃうのがおかしいのか、それとも Azure 上の .NET Core で DbSet 同士の Join ができないのがおかしいのか。

どちらにせよ、同じコードをローカル PC と Azure 上で動かしたときに、挙動が違うのは「おかしい」ので、ここは調べないといけない。これ、Linux 上の .NET Core だとどうなのだろうか? 後で調べるか思案中。

追記 2017/05/11

Ubuntu に donet 1.0.3 をインストールして構築してみると、上の Join が動くようになったので、Azure 上だけがダメな模様。

Azure の App Service のコンソールでバージョンを調べると doetnet コマンド自体が 1.0.1 、.net core のバージョンが Version  : 1.1.0-preview1-001100-00 になっているので、この違いと思われる。ちなみに、ローカルPC の場合は、1.1.0 になっている。この微妙な差(Azure のほうが previewのままなのが)原因らしい。

Build 2017 の微妙な時期なので、これが終わると 2.0 にアップデートされるかもしれん。

追記 2017/05/19

現時点で、.NET Command Line Tools (2.0.0-preview1-005977)  になっているので、join が正常に動いている。やったー。

カテゴリー: Azure, OpenCCPM パーマリンク