2022年
ASP.NETCore(EF Core)
2.2~6.0の旅
masanori_msl@【オンライン】.NET 5 終了目前! C# Tokyo イベント 2022/04/28
About me
 Name:Masui Masanori
 Work:無茶ぶり処理班
 Twitter:https://twitter.com/masanori_msl
 Blog:http://mslgt.hatenablog.com/
https://dev.to/masanori_msl
.NET Core 2.2時代に作った
ASP.NET Core(+ EF Core)の
プロジェクトを.NET 6に更新しました
やったこと
• .NET Core ver.2.2.207
• .NET Core ver.3.1.418
• .NET ver.5.0.407
• .NET ver.6.0.202
https://github.com/masanori840816/UpgradeProjectSample
サンプルコード(作りかけ)
お話しすること
更新したときに発生したエラーとその対処
必須ではないが変更した方が良いと感じた機能いくつか
ドキュメント
Microsoft Docsに各バージョンの移行ガイド、
破壊的変更がまとめられているので、
詳細はそちらをご確認ください。
ASP.NET Core 5.0 から 6.0 への移行
https://docs.microsoft.com/ja-jp/aspnet/core/migration/50-to-60
互換性に影響を与える変更点
https://docs.microsoft.com/ja-jp/dotnet/core/compatibility/
【2.2 → 3.1】
今回一番大きな変更が入ったバージョン。
ver. 3.0 → ver.3.1 は破壊的変更が
ほぼないためまとめています。
【2.2 → 3.1】【必須】Startup.cs
• AddMvc()、 UseMvc()がAddController()、UseRouting()、UseEndpoints()に
• UseAuthentication() がUseAuthentication() とUseAuthorization()に分割
• Razorを使う場合、AddRazorPages()が必要に
• IHostingEnvironmentがIWebHostEnvironmentに変更
【2.2 → 3.1】【必須】ASP.NET Coreのパッケージ削除
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App"/>
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All"/>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.24"/>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.18"/>
<PackageReference Include="NLog.Web.AspNetCore" Version="4.14.0"/>
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.24"/>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.24"/>
</ItemGroup>
</Project>
不要
【2.2 → 3.1】【必須】Newtonsoft.Json→System.Text.Json
デフォルトのJSONライブラリがNewtonsoft.JsonからSystem.Text.Jsonに
変更されました。
ただし、NuGetでNewtonsoft.Jsonを追加することは可能なため、
移行の余裕がない場合はこちらの方法をお勧めします。
(ver.3.1 で止める場合は Newtonsoft.Json の方が良いかもしれません)
【2.2 → 3.1】【必須】Raw SQL実行のメソッド変更
FromSql()からFromSqlRaw()に変更されました。
これにより、WhereやOrderByをLINQで書くことが可能になりました。
var query = this.context.SearchedBooks
.FromSqlRaw("SELECT b.id AS "BookId", b.language_id AS "LanguageId", b.name AS
"BookName", a.name AS "AuthorName" FROM book b INNER JOIN author AS a ON b.author_id =
a.id");
if(string.IsNullOrEmpty(criteria.Name) == false)
{
query = query.Where(b => b.BookName.Contains(criteria.Name));
}
return await query
.OrderBy(b => b.BookId)
.ToListAsync();
【2.2 → 3.1】【必須】LINQでクライアントサイド実行をしな
い
var languages = await this.context.Languages
.Where(L => languageIds.Contains(L.Id))
.ToListAsync();
if(languages.Count <= 0)
{
return new List<Book>();
}
return await this.context.Books
.Where(b => languages.Any(L => L.Id == b.LanguageId))
.ToListAsync();
地味に引っかかった変更。
下記の下から2行目のように、直接SQLに変換できないコードを書くと、
実行時エラーが発生するようになりました。
対応方法は、下記の場合はlanguagesからId (int) のみを取り出した配列を作り、
languages.Any~ を ids.Contains(b.LanguageId) に置き換える、LINQ 実行前に
AsEnumerable() を挟む (ToListAsync() はできなくなります)などが考えられます。
【2.2 → 3.1】Nullable Reference Type
C# 8の機能としてNullable Reference Typeが追加されました。
EF Coreでも使用可能ですが、DBのテーブルのNot Null設定と紐づけられるので
注意は必要です。
Working with Nullable Reference Types – Microsoft Docs
https://docs.microsoft.com/en-us/ef/core/miscellaneous/nullable-reference-types
【2.2 → 3.1】Transaction、Commit、Rollback
Transactionを {} で囲まなくてもよくなりました。
また非同期版の Commit 、Rollback が追加されました。
using var transaction = await this.context.Database.BeginTransactionAsync();
try
{
var author = await this.authors.GetOrCreateAsync("sample author");
await this.books.CreateAsync(author, new Book
{
Name = bookName,
LanguageId = LanguageData.GetEnglish().Id,
});
await transaction.CommitAsync();
}
catch(NpgsqlException ex)
{
await transaction.RollbackAsync();
}
【2.2 → 3.1】その他
.NET Framework上で動作しなくなる
dotnet ef ツールが .NET Core SDKに含まれなくなる
Blazorの登場
【3.1 → 5.0】
変更必須の個所はありませんでした。
【3.1 → 5.0】record、init only setter property
初期化時のみ値を変更可能にする record と init only setter property。
EF Coreのモデルクラスにも使用可能なので、
使えるところにはガンガン使っていくスタイルで登場させています。
【3.1 → 5.0】その他
.NET Core から .NET へ
.NET Framework の統合
Windows Runtime API がWPF、WinFormsから使いやすくなった
【5.0 → 6.0】
必須で変更が必要な個所はEF Coreで一か所。
必須ではないもののASP.NET Coreの
テンプレートの変更もインパクトが大きい印象です。
【5.0 → 6.0】【必須】DateOnly、TimeOnly、UTC
PostgreSQLの date や time 、timestamp 型に対する C# の対応クラスが変更。
DateTime のままだと更新時に例外が発生します。
date → DateOnly
time → TimeOnly
timestamp → DateTimeのまま。ただし UTC への変換が必要。
※ DateOnly 、 TimeOnly は JSON に変換できないため、 DateTime への変換が
必要になります。
Date and Time Handling – Npgsql Documentation
https://www.npgsql.org/doc/types/datetime.html
【5.0 → 6.0】【必須】テンプレート名変更
dotnet new コマンドでプロジェクトを作る時のテンプレート名が変わりました。
dotnet new <テンプレート> - .NET CLI | Microsoft Docs
https://docs.microsoft.com/ja-jp/dotnet/core/tools/dotnet-new
【5.0 → 6.0】トップレベルステートメント
C# 9 (.NET 5) で導入されたトップレベルステートメントが、
テンプレートでも使用されるようになりました。
結果、.NET 6 でプロジェクトを作ると Program.cs 、 Startup.cs に分かれていた
処理が Program.cs にまとまって作成されるようになりました。
今まで通りの書き方でも普通に動くので、新しい書き方に揃えたいなど、
理由がなければ放置でよいかもしれません。
namespace UpgradeProjectSample
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello");
}
}
}
Console.WriteLine("Hello");
【5.0 → 6.0】ImplicitUsings
有効にすることで using System; などを書かなくてもよくなりました。
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
using Microsoft.EntityFrameworkCore;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
不要
アップデート方法?
変更点が大きいのは 2.2 → 3.0 と 5.0 → 6.0。
いずれにせよ EF Coreは対応が必要なので、いっぺんにやっても良いかも。
難しいなら 2.2 → 3.1 → 6.0
Thank you!

2022年ASP.NETCore2.2~6.0の旅.pptx