Ignite 2019 のタイミングで Azure Functions v3 のプレビューが正式に公開されましたが、Azure Functions SDK 側の問題で .NET Standard 2.1 ターゲットのライブラリ*1が使えなかったので弄って来ませんでした。
その後 Runtime も一時的に非公開になりましたが、最近全て解決したので試します。現在 v3 はプレビューとプレリリースの 2 種類が公開されています。
プレビューとプレリリースの差が分かりにくいですが、今のところはプレリリースの方が新しい Core Tools とテンプレートとなっています。それぞれの違いは大体以下の通りです。
- v3-preview
- .NET Core 3.0 (
netcoreapp3.0
) - Functions SDK v1.0.30-beta2
- Core Tools v3.0.4
- .NET Core 3.0 (
- v3-prerelease
- .NET Core 3.1 (
netcoreapp3.1
も使える) - Functions SDK v3.0.1
- Core Tools v3.1.0
- .NET Core 3.1 (
次の更新ぐらいで v3-preview にも v3-prerelease の内容が降ってくると思うので、v3 のプレビュー中は v3-prerelease を使っておいた方が良さそうな気配です。
Azure Functions v3 の GA 時には .NET Core 3.1 がターゲットになるので、実際にデプロイしたいケースを除いて v3-prerelease 版が出た今となっては .NET Core 3.0 向けを弄る必要はないです。
Timelines
Azure Functions 3.0 · Issue #200 · Azure/app-service-announcements · GitHub
A public preview will be available in October 2019
General Availability, running on .NET Core 3.1 (LTS release), scheduled for Q1 2020
今のところ v3 に必要な .NET Core 3.1 が App Service にデプロイされていないのと、Functions Runtime が古いままなので v3-prerelease をデプロイ可能になるには少し時間がかかります。
App Service の .NET Core 3.1 対応は 12/13 頃に完了する予定らしいです。リージョンやスケールユニットによって多少は前後しそうですが、LTS 版が早めに展開されるのは喜ばしいですね。
前置きはこのくらいにして、実際に Entity Framework Core 3.1 を使う Azure Functions のコードを書いてみることにします。v3-prerelease を使っていきます。
Azure Functions v3 のプレビュー / プレリリースは環境変数を設定しないと出てこないので、以下の記事を参照して設定を追加する必要があります。ユーザー環境変数に追加して VS の再起動で OK です。
Functions SDK はこれまでの 1.0.x
から一気に上がって 3.0.1
になりました。SDK はプレリリース版になっていないですが、依存関係は netcoreapp3.0
になっているので v3 専用です。
v3-prerelease を選んでプロジェクトを作成し、Microsoft.EntityFrameworkCore.SqlServer
と DI 用の Microsoft.Azure.Functions.Extensions
をインストールします。最近の Azure Functions ではインスタンスのライフサイクル管理のために DI を使うのが一般的です。
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netcoreapp3.1</TargetFramework> <AzureFunctionsVersion>v3-prerelease</AzureFunctionsVersion> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.0" /> <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.1" /> </ItemGroup> <ItemGroup> <None Update="host.json"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> <None Update="local.settings.json"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToPublishDirectory>Never</CopyToPublishDirectory> </None> </ItemGroup> </Project>
デフォルトでは netcoreapp3.0
で作成されますが、手動で netcoreapp3.1
に変更しました。
DI 周りと Entity Framework Core を使うためのコードは以下のように用意しました。エンティティ周りは適当に用意して、接続文字列は SQL Database Serverless を作成して設定しました。
public class Startup : FunctionsStartup { public override void Configure(IFunctionsHostBuilder builder) { builder.Services.AddDbContextPool<AppDbContext>(options => options.UseSqlServer(Environment.GetEnvironmentVariable("DefaultSqlConnection"))); } } public class AppDbContext : DbContext { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } public DbSet<Blog> Blogs { get; set; } } public class Blog { public int Id { get; set; } [Required] public string Title { get; set; } [Required] public string Body { get; set; } [Required] public DateTime CreatedAt { get; set; } }
あまり見ないであろう AddDbContextPool
を使っているのは何となくです。作成してある SQL Database Serverless 側にテーブルを作成して、適当なデータを追加しておきました。
Function 本体はコンストラクタで AppDbContext
を受け取って、関数の本体で利用しているだけです。単純に DB に入っているものを JSON として返すだけの簡単なコードです。
public class Function1 { public Function1(AppDbContext appDbContext) { _appDbContext = appDbContext; } private readonly AppDbContext _appDbContext; [FunctionName("Function1")] public async Task<IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req, ILogger log) { log.LogInformation($".NET Core Version: {Environment.Version}"); var list = await _appDbContext.Blogs.ToListAsync(); return new OkObjectResult(list); } }
Visual Studio からデバッグ実行すると、.NET Core 3.1 で動作していることがログから確認できます。
Entity Framework Core 周りでもエラーが出ることなく、DB からデータを取得して応答が返ってくることが確認できました。サクッと .NET Core 3.1 / .NET Standard 2.1 のライブラリが使えたので内容が地味です。
自分は使う予定が今のところないですが .NET Core に対応した Entity Framework 6 も .NET Standard 2.1 がターゲットなので、Azure Functions v3 で使えるようになっているはずです。
少し前に v2 と v3 で Cold start 周りの検証をしたところ、v3 の方が応答時間のばらつきが少なかったのでパフォーマンス面でも v3 のリリースを割と期待しています。*2
*1:Entity Framework Core 3.0 のこと