【PR】この記事には広告(アフィリエイトリンク)を含みます。
.NET 8 のサポートは 2026年11月10日に終了します。そして .NET 9 も同じ日に終了します。LTS の8と STS の9が同じ日に切れるという、少し変わった形です。
この記事は「自分のアプリは対象なのか」「移行しないと何が起きるのか」「実際に何を順番にやればいいのか」を、個人開発者と小規模受託の目線でまとめたものです。ニュース記事ではなく、手を動かすためのチェックリストとして書いています。
- 期限は 2026年11月10日。.NET 8(LTS)と .NET 9(STS)が同じ日に終了します。.NET 9 は STS のサポート期間が18ヶ月から24ヶ月に延びた結果、.NET 8 と並びました。
- その日にアプリが止まるわけではありません。止まるのはセキュリティ更新と技術サポートです。動き続けるからこそ、放置すると「直せない脆弱性を抱えたまま動く」状態になります。
- 移行先は .NET 10(LTS・2028年11月14日まで)。
<TargetFramework>をnet10.0に変えるところから始めます。LTS から LTS への移行なので、.NET Framework からの移行に比べれば比較的素直です。 - 「今は移行しない」も、条件つきで成立する判断です。オフラインの社内ツールのように攻撃面が小さいものまで、期限に追われて壊す必要はありません。ただし期限を知ったうえで選ぶことと、知らずに放置することは別物です。
記事内のバージョン・日付は 2026年8月20日に .NET 公式サイトのサポートポリシーと Microsoft Learn で確認した内容です。日付やパッケージの対応状況は変わることがあるので、作業の前に必ず公式ページで最新の情報を確認してください。

まず確認:自分のアプリは .NET 8 サポート終了の対象か
ニュースを読んで不安になっても、自分の環境を見ないことには何も始まりません。確認するのは2箇所だけです。
1. 手元のマシンに何が入っているか(SDK とランタイム)
# 入っている SDK の一覧
dotnet --list-sdks
# 入っているランタイムの一覧(アプリを動かす側)
dotnet --list-runtimes
# まとめて見る
dotnet --infodotnet --list-sdks の出力例はこうなります。
8.0.414 [C:\Program Files\dotnet\sdk]
10.0.100 [C:\Program Files\dotnet\sdk]ここでよくある勘違いが「dotnet --version を見れば分かる」というものです。dotnet --version が返すのは「いま使われる SDK のバージョン」1つだけで、global.json の指定があればそれに従います。入っているものの全体像は --list-sdks と --list-runtimes(まとめて見るなら --info)で確認します。
そしてSDK とランタイムは別物です。開発マシンに .NET 10 SDK が入っていても、本番サーバーに .NET 10 のランタイムが無ければアプリは起動しません。逆に本番サーバーには SDK は要らず、ランタイム(Microsoft.NETCore.App / Microsoft.AspNetCore.App)だけあれば動きます。確認は「開発機」と「本番」の両方で行ってください。
2. プロジェクトが何を狙っているか(TargetFramework)
本体はこちらです。.csproj を開いて <TargetFramework> を見ます。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>net8.0 または net9.0 になっていれば、この記事の対象です。プロジェクトが増えてくると1つずつ開いていられないので、まとめて洗い出します。
# macOS / Linux / Git Bash
grep -rn "<TargetFramework" --include=*.csproj .# Windows PowerShell
Get-ChildItem -Recurse -Filter *.csproj |
Select-String -Pattern "<TargetFramework"複数ターゲットの <TargetFrameworks>(複数形)を使っているライブラリもあるので、<TargetFramework の前方一致で検索するのがコツです。片方だけ引っかけて見落とすのが、地味にありがちな事故です。
dotnet --list-sdks… 開発機の SDK。ビルドする側dotnet --list-runtimes… 本番サーバーにも必要。動かす側.csprojの<TargetFramework>/<TargetFrameworks>… これがnet8.0/net9.0なら対象global.json… SDK のバージョンを固定している場合がある(後述のハマりどころ)
なぜ .NET 8(LTS)と .NET 9(STS)が同じ日に終わるのか
ここは誤解が多いところなので、先に仕組みから整理します。
.NET のサポートポリシーは、次のルールで動いています(2026年8月20日時点の公式サポートポリシーの記載)。
- 新しいメジャーリリースは毎年11月に公開される
- 偶数番号が LTS(Long Term Support)=3年
- 奇数番号が STS(Standard Term Support)=2年
この「STS=2年」が効いています。STS のサポート期間は以前は18ヶ月でしたが、24ヶ月に延長されました。その結果、2024年11月12日にリリースされた .NET 9 の期限が 2026年11月10日になり、2023年11月14日リリースの .NET 8(LTS・3年)の期限と同じ日に並びました。
| バージョン | リリース | 種別 | サポート終了 |
|---|---|---|---|
| .NET 10 | 2025年11月11日 | LTS | 2028年11月14日 |
| .NET 9 | 2024年11月12日 | STS | 2026年11月10日 |
| .NET 8 | 2023年11月14日 | LTS | 2026年11月10日 |
| .NET 7 | 2022年11月8日 | STS | 2024年5月14日(終了済み) |
| .NET 6 | 2021年11月8日 | LTS | 2024年11月12日(終了済み) |
つまり「LTS の .NET 8 を選んでおけば .NET 9 より長く安心」という直感は、この期に限っては成立しません。8 も 9 も同じ日です。「うちは LTS だから来年でいいだろう」と思っていた人ほど、いま確認しておいたほうがいい理由がここにあります。
なお、サポートを受け続けるには各バージョンの最新パッチを当てていることが前提になります。8.0.x の x が古いまま止まっているなら、そこも合わせて確認しておきたいところです。
移行しないとどうなるか(アプリが止まるわけではない)
ここを正確に理解しておくと、社内やクライアントへの説明が一気に楽になります。
Microsoft の .NET Blog は、サポート終了後について次のように説明しています。
- アプリケーションは動き続ける
- ただし 「どちらのバージョンにも新しいセキュリティ更新は提供されない」
- 技術サポートも受けられなくなる
- 結果として、修正されない脆弱性を抱えたまま使い続けることになる
「11月10日に一斉に動かなくなる」わけではありません。止まらないからこそ厄介、というのが実務の感覚に近いです。放置しても表面上は何も起きないので、気づいたときには数年分の未修正の穴を抱えている、という形になりやすい。
実際に効いてくるのは、次のようなところです。
- セキュリティ更新が来ない。.NET 本体やランタイムに脆弱性が見つかっても、対象バージョンへの修正は出ません
- コンテナで動かしている場合、ベースイメージも同じ扱いになります。
8.0系のタグのイメージを使い続ける前提なら、いつまで更新されるかを公式のサポートポリシーで確認しておく必要があります - 依存パッケージ側の対応が先に切れることがあります。ライブラリが新しい TFM だけを対象にし始めると、セキュリティ修正を取り込むために結局アップグレードが必要になります
- 取引先の要件として「サポート期間内のランタイムであること」が求められる場合があります。セキュリティチェックシートや監査で聞かれる項目になっていることがあり、その場で答えられないと面倒です
なお、自分が開発者ではなく「.NET 8 / 9 で作られたアプリを使っている側」の場合、Microsoft はソフトの開発元やベンダーに連絡して更新版を求めることを案内しています。受託でアプリを納品している立場なら、問い合わせが来る前にこちらから連絡しておくほうが印象がいい話でもあります。
移行先:.NET 10 は LTS で 2028年11月14日まで
移行先は .NET 10 です。
- リリース日
-
2025年11月11日 サポート種別:LTS(Long Term Support) サポート終了:2028年11月14日 C# のバージョン:C# 14(2025年11月リリース)
.NET 8 → .NET 10 は「LTS から LTS」への移行です。.NET Framework 4.x から .NET へ移すような作りの違いはなく、基本は TFM を書き換えて、パッケージを上げて、壊れたところを直すという流れになります。「移行」という言葉から想像するほど大掛かりではないケースが多い、というのが現実的な見通しです。
ちなみに C# のバージョンは TFM に連動します。Microsoft Learn には「ターゲットの TFM に関連付けられたバージョンより新しい C# 言語バージョンを使うことはサポートされない」と明記されており、Visual Studio でも言語バージョンの UI が既定で無効になっています(TFM を変えることで言語バージョンが変わる設計)。C# 14 の機能を使いたいなら、TFM を net10.0 にするのが正規のルートです。<LangVersion>latest</LangVersion> で無理に上げるのは、公式ドキュメントでも「マシンによって結果が変わりビルドが不安定になる」として非推奨とされています。
この記事の守備範囲(他の記事との役割分担)
この記事は「期限の把握と、移行するかどうかの判断、そして移行作業の全体手順」を担当します。データベース周りを C# でどう書くか(Dapper・EF Core・SqlKata の使い分けや実際のコード)は、DBアクセスのハブ記事にまとめてあります。

また、そもそも開発環境をどこに置くか(特に Mac の人)で迷っている段階なら、先にこちらを読んだほうが遠回りになりません。

移行するか決める:判断フロー
全部を一律に上げる必要はありません。アプリごとに判断するのが現実的です。

上から順に見て、当てはまったところで決めてしまって構いません。「移行しない」を選ぶ条件は後述しますが、先に移行する場合の手順を通しで見ておきます。
.NET 10 への移行チェックリスト(実務でやる順番)
順番が大事です。TFM を変える → パッケージを上げる → 警告を潰す → 破壊的変更を見る → 動作確認 → 本番反映。この順で進めると、問題が出たときに「どの操作で壊れたか」が切り分けられます。

作業前にブランチを切って、ステップごとにコミットしてください。まとめて1コミットにすると、動かなくなったときに戻れなくなります。
STEP1:TargetFramework を net10.0 に変える
まずはこれだけです。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>ライブラリで複数バージョンを同時にサポートしたい場合は、複数ターゲットにします。
<PropertyGroup>
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
</PropertyGroup>変えたらビルドします。この時点で通るなら、大きな山は越えています。
dotnet buildここで大量にエラーが出るなら、原因はたいてい次のステップ(パッケージ側)にあります。
STEP2:NuGet パッケージの対応を確認する
TFM を上げただけでは、NuGet パッケージは古いままです。ここが実は本丸で、net10.0 でビルドが通っても、サポートが切れたパッケージを使い続けていたら意味が薄いというケースがあります。
.NET 10 SDK では、パッケージの棚卸しコマンドが使えます。
# 更新があるパッケージを一覧(.NET 10 SDK は名詞が先)
dotnet package list --outdated
# 既知の脆弱性があるパッケージを一覧
dotnet package list --vulnerable
# 非推奨(deprecated)になったパッケージ
dotnet package list --deprecated
# 間接的に入っているパッケージも含めて見る
dotnet package list --include-transitive --vulnerable⚠️ コマンドの語順が変わっています。Microsoft Learn には「.NET 9 SDK 以前を使っているなら動詞が先の形(dotnet list package)を使うこと。名詞が先の形は .NET 10 で導入された」と明記されています。古い手順書をコピペして「そんなコマンドは無い」と言われるのは、この移行期に踏みがちなところです。
# .NET 9 SDK 以前ならこちら(動詞が先)
dotnet list package --outdatedなお --vulnerable は .NET SDK 9.0.300 以降で使えるオプションです。また .NET 10 では dotnet package list が必要に応じて自動で復元してから結果を出すようになりました(それ以前は先にビルド/復元しておく必要があります)。
このサイトで扱ってきたパッケージは、実際どうなるか
このブログで書いてきた DB 周りのパッケージについて、2026年8月20日時点で NuGet 公式ページに表示されている対応ターゲットを並べます。

いちばん注意が必要なのは EF Core です。Microsoft Learn の「EF Core releases and planning」には、次のように書かれています。
- EF Core 10.0 のターゲットフレームワークは .NET 10、サポートは 2028年11月10日まで
- EF Core 9.0 と 8.0 のターゲットフレームワークは .NET 8、サポートは 2026年11月10日まで(=.NET 8 / 9 本体と同じ日)
- EF Core のリリースとサポートは .NET のリリース・サポートと足並みをそろえている
なお、EF Core 10.0 の 2028年11月10日は、この記事の表に載せた .NET 10 本体の期限(2028年11月14日)と4日ずれています。これは誤植ではなく、Microsoft Learn の EF Core ページと .NET 公式サポートポリシーの表記差で、どちらも2026年8月20日時点の公式表記のまま引いています。
つまり、EF Core を 10 系に上げるには .NET 10 が必要です。「TFM は net8.0 のままで EF Core だけ最新にする」はできません。そして EF Core 9 を使い続ける選択は、2026年11月10日以降は「サポート外の ORM を使う」ことになります。EF Core を使っているなら、.NET 10 への移行と EF Core 10 への更新はセットの作業だと考えてください。
同じページには、メジャーバージョンの更新について「メジャーバージョンの更新(EF Core 9 → 10 など)には破壊的変更が含まれることが多いので、十分なテストを推奨する」とも書かれています。EF Core 10 の破壊的変更は専用ページにまとまっているので、EF Core を使っているプロジェクトではそこだけは必ず目を通す価値があります。
EF Core の基本的な使い方や、他のアプローチとの違いは既存記事にあります。
一方 Dapper は netstandard2.0 まで含めて広くターゲットを取っているので、TFM を上げても素通りすることが多いパッケージです。Npgsql も .NET 8 / 9 / 10 の3つに対応しているため、.NET 10 に上げても、.NET 8 に留まっても使えます。Microsoft.Data.Sqlite は .NET Standard 2.0 を基準に広い互換性を持っていますが、EF Core と同じリリース系列で番号が動くので、EF Core を上げるときは一緒に上がると思っておくといいです。
SqlKata のように更新間隔が長いパッケージは、「対応 TFM の表記上は動くはず」で終わらせず、自分のプロジェクトで実際に動かして確認するのが安全です。SQL 組み立て系はコンパイルが通っても生成される SQL が変わる形で問題が出ることがあるので、生成結果を比較しておくと安心できます。
STEP3:ビルド警告を潰す
エラーが消えたら、次は警告です。警告は「今は動くが、将来の削除・変更が予告されているもの」を教えてくれるので、移行のタイミングで潰しておくと後が楽になります。
# 詳細を出す
dotnet build -v normal
# 一時的に警告をエラー扱いにして、見落としを防ぐ
dotnet build -warnaserror特に見ておきたいのが、API の廃止予定(obsoletion)を示す警告です。.NET 10 でも「API obsoletions」として、コアライブラリと Windows Forms でまとまった数の API に廃止予定の印が付いています。ここで出た警告は、将来の削除・変更の予告として扱われているものです。.NET は互換性を重視するので即座に消えるわけではありませんが、移行のついでに片付けておくのが安全です。
.csproj に恒久的に入れておくなら、こう書けます。
<PropertyGroup>
<!-- 全部まとめてエラーにするなら(作業が止まりやすいので移行中は非推奨) -->
<!-- <TreatWarningsAsErrors>true</TreatWarningsAsErrors> -->
<!-- 段階的にやるなら、対象を絞る。
CS0618 = 廃止予定 API の使用(警告)。
CS0619 は [Obsolete(..., error: true)] の診断で最初からエラーなので指定不要。 -->
<WarningsAsErrors>CS0618</WarningsAsErrors>
</PropertyGroup>いきなり全部エラーにすると作業が止まるので、移行中は -warnaserror をコマンドラインで一時的に付けて確認だけする運用が扱いやすいです。
STEP4:破壊的変更を確認する
Microsoft Learn には「.NET 10 での破壊的変更」というページがあり、ASP.NET Core・コンテナ・コアライブラリ・暗号化・EF Core・拡張機能・グローバリゼーション・インストールツール・相互運用・ネットワーク・リフレクション・SDK と MSBuild・シリアル化・Windows Forms・WPF などの分類で一覧になっています。
変更は3種類に分けられています。この分類を知っておくと、影響範囲の見積もりが速くなります。
- バイナリ非互換:新しいランタイムで既存のバイナリが読み込めない・実行できないことがある(再コンパイルが必要)
- ソース非互換:新しい SDK で再コンパイルすると、コードの修正が必要になることがある
- 動作の変更:コードもバイナリもそのままだが、実行時のふるまいが変わる
いちばん怖いのは3つ目です。ビルドも通るしテストも通るのに、本番でだけ挙動が違うという形で出てくるからです。
.NET 10 の破壊的変更で、個人開発・小規模受託が踏みやすいもの(クリックで開く)
Microsoft Learn の一覧から、この記事の読者に関係しやすいものを抜き出します(同ページには「この記事は作成中で、破壊的変更の完全な一覧ではない」と注記されています。必ず原典を確認してください)。
SDK / MSBuild
- バージョン指定のない
PackageReferenceがエラーになる(NU1015) dotnet restoreが推移的なパッケージも監査対象にする- NuGet の監査ソースで、既定では安全でない HTTP が許可されなくなった
dotnet package list/dotnet package searchの HTTP 警告がエラーに格上げdotnet new slnの既定が SLNX 形式にdotnet watchのログが stdout ではなく stderr へ- ワークロードの既定構成が「loose manifests」から「workload sets」モードに
社内 NuGet サーバーを HTTP で運用している場合は、少し整理が要ります。パッケージソースの HTTP 禁止(NU1302)は .NET 9 SDK の時点ですでにエラーになっていて、nuget.config に allowInsecureConnections="true" を書いて回避している現場が多いはずです。.NET 10 で新しく加わるのは、auditSources に HTTP を指定している場合に restore がエラーになる点(NU1302・.NET 10.0.400 SDK 以降)と、dotnet package list / dotnet package search が HTTP ソースでエラーになる点の2つです。監査ソースを明示していない現場は、前者の影響を受けません。
シリアル化
- System.Text.Json がプロパティ名の衝突をチェックするようになった
- XmlSerializer が
[Obsolete]の付いたプロパティを無視しなくなった
JSON の API を持っているアプリは、ここで例外が出る可能性があります。
コアライブラリ
BufferedStream.WriteByteが暗黙のフラッシュをしなくなった- .NET ランタイムが既定の終了シグナルハンドラーを提供しなくなった(SIGTERM)
- C# 14 の span 引数を含むオーバーロード解決の変更
System.Linq.AsyncEnumerableがコアライブラリに入った(同名の型を自前や外部パッケージで持っていると衝突しうる)
ネットワーク・暗号化・コンテナ
Uriの長さ制限が撤廃- Unix では OpenSSL 1.1.1 以降が必須、macOS では OpenSSL の暗号プリミティブが非対応に
- 既定の .NET コンテナイメージが Ubuntu ベースに
Linux サーバーや VPS にデプロイしている場合、OpenSSL のバージョン要件は事前に確認しておきたい項目です。コンテナのベースイメージが変わる件も、イメージサイズやインストール済みパッケージの前提が変わるので、Dockerfile を持っているなら見ておいてください。
デスクトップアプリ(WinForms / WPF)
- WPF と WinForms を両方参照しているアプリは
MenuItemとContextMenuの型を明示する必要がある StatusStripの既定レンダリングが System RenderMode に- 空の
ColumnDefinitions/RowDefinitionsが禁止に(WPF) DynamicResourceの誤用でアプリがクラッシュするように(WPF)
自分のアプリで使っている領域だけ見ればいいので、全部読む必要はありません。ASP.NET Core を使っていないなら ASP.NET Core の節は飛ばしていい、というくらいの温度感で構いません。
STEP5:動作確認(ここを飛ばすと本番で気づく)
ビルドが通ったからといって終わりではないのが、STEP4 の「動作の変更」があるからです。
# テストを回す
dotnet test
# 実際に動かす
dotnet runテストがあるならまず回す。無いなら、最低限「お金・日付・文字コード・DB の書き込み」に関わる経路だけは手で確認してください。この4つは、動作の変更が起きたときにいちばん痛い場所です。
データベースを使っているアプリでは、次のあたりを見ておくと安心できます。
- マイグレーションが通るか(EF Core を 10 に上げたなら特に)
- 生成される SQL が変わっていないか(EF Core・SqlKata。ログ出力を before / after で比較する)
- 日時の扱い(
DateTime/DateTimeOffsetと、DB 側の型のマッピング) - 接続文字列と暗号化まわり(SQLite の暗号化 DB を使っているなら、ネイティブライブラリの再取得も含めて確認)
暗号化 SQLite のようにネイティブライブラリを噛むものは、ランタイムが変わると復元されるネイティブアセットが変わることがあります。ここは「動くはず」で済ませず、実際に開いて読み書きするところまで確認してください。関連する手順は暗号化された SQLite に接続するとC# で SQLite に接続する準備にまとめてあります。
STEP6:本番反映
最後に本番です。ここで押さえるのは3つ。
- 本番サーバーに .NET 10 のランタイムを入れる(SDK は不要)。ASP.NET Core アプリなら
Microsoft.AspNetCore.Appも必要です - 旧バージョンのランタイムをすぐ消さない。.NET は複数バージョンのランタイムを並べて置けます。切り戻し先を残しておくと安心です
- ロールバック手順を決めてからデプロイする。「戻し方が分からない状態でリリースする」のがいちばん事故ります
自己完結型(self-contained)で発行しているなら、サーバー側にランタイムを入れる必要はありません。その代わりランタイムのセキュリティ更新は自分で再発行して配ることになるので、どちらの方式かで運用が変わる点は意識しておいてください。
反映後は、ホスト側でも確認しておきます。
# 本番サーバーで、狙ったランタイムが入っているか
dotnet --list-runtimes
# アプリが実際にどのランタイムで動いているか(起動ログや診断で確認)
dotnet --info「入れたつもり」を反映確認で潰すのは、サーバー作業の基本です。ここは VPS の設定と同じ考え方ですね。
移行でハマりやすいところ(4つ)
手順どおりにやっても引っかかる箇所を、先に挙げておきます。
1. global.json で SDK が固定されていて上がらない
global.json があると、そこに書かれた SDK が使われます。.NET 10 SDK を入れたのに古い SDK でビルドされるときは、まずこれを疑ってください。
# 使われている SDK を確認
dotnet --version
# 入っている SDK を全部確認(--version との差を見る)
dotnet --list-sdksglobal.json の例です。
{
"sdk": {
"version": "10.0.100",
"rollForward": "latestFeature"
}
}リポジトリ直下だけでなく親ディレクトリの global.json も効くので、「置いた覚えがないのに固定されている」ときは上の階層まで探してください。
2. SDK は入っているのにランタイムが無い(またはその逆)
前述のとおりですが、実際に踏むのはたいてい本番サーバーです。「開発機では動いたのに本番で起動しない」の大半がこれです。dotnet --list-runtimes でホスト側に実物があるかを確認するのを、デプロイ手順に組み込んでしまうのが早いです。
3. dotnet list package と dotnet package list の語順
STEP2 で触れたところです。.NET 10 SDK では名詞が先(dotnet package list)、.NET 9 SDK 以前では動詞が先(dotnet list package)。移行期は開発機に両方の SDK が入っていることが多いので、「昨日は動いたのに」という混乱が起きます。手順書やスクリプトを持っているなら、この機会に書き換えておくといいです。
4. .NET Upgrade Assistant は非推奨になっている
移行ツールとして名前が挙がりやすい .NET Upgrade Assistant ですが、Microsoft Learn の同ツールの概要ページには「.NET Upgrade Assistant is officially deprecated(正式に非推奨)」と明記されています(2026年8月20日確認)。代わりに案内されているのは GitHub Copilot の modernization チャットエージェントで、Visual Studio 2026 および Visual Studio 2022 17.14.16 以降に含まれるとされています。プロジェクトと依存関係を解析して移行計画を作り、変更ごとにコミットするので検証や巻き戻しがしやすい、という説明です。
古い記事を見て Upgrade Assistant を前提に計画を立てると、情報が1世代ずれます。ツールに頼る場合は、まず現在どれが推奨されているかを Microsoft Learn で確認するのが安全です。もっとも、net8.0 → net10.0 の移行はこの記事の6ステップで手作業でも十分回せる規模なので、ツールは必須ではありません。
「移行しない」という判断もある
正直に書きます。全部を期限までに上げる必要はありません。
移行しない選択が成立しやすいのは、たとえばこんなケースです。
- オフラインまたは閉じたネットワークでしか動かない社内ツール。外部からの入力を受けないなら、脆弱性が悪用される経路自体が小さい
- すでに使われていない・使う予定のないアプリ。移行するより「止める」ほうが正しいこともあります
- 今期の予算・工数がどうしても取れない受託案件。この場合は、移行が必要なことをクライアントに文書で伝えたうえで、時期を合意して先送りするのが誠実な進め方です
ただし、条件があります。
- 期限を知ったうえで選ぶこと。知らずに放置しているのとは意味が違います
- セキュリティ更新が来ない前提で運用すること。外部公開しない、機微なデータを置かない、といった線引きをセットにします
- 依存パッケージ側の更新も止まっていく前提を持つこと。時間が経つほど、後から移行するときの段差は大きくなります
- 再開するときは「移行から始める」と決めておくこと。機能追加の途中で移行が挟まると、原因の切り分けができなくなります
逆に、外部に公開しているもの・クライアントに納品したもの・今後も保守を続けるものは、期限内に上げておくほうが、結果的に安く済むことが多いはずです。先送りするほど、次のバージョンとの差が広がって作業量が増えるからです。.NET 6 のまま止まっているプロジェクトを .NET 10 に上げるほうが、.NET 8 から上げるより大変なのは想像がつくと思います。
.NET Framework は別ライフサイクル(「来年終わる」は誤解)
ここは毎回混乱するところなので、はっきり分けておきます。
.NET Framework 4.8 / 4.8.1 は、この記事の期限とは無関係です。
.NET 公式の .NET Framework サポートポリシーには、次のように書かれています(2026年8月20日確認)。
- .NET Framework は 4.5.2 以降、Windows の「コンポーネント」として定義されており、親となる OS と同じサポートを受ける
- .NET Framework 4.8(2019年4月18日)と 4.8.1(2022年8月9日)はいずれもサポート中で、個別のサポート終了日は設定されていない
- サポートされている Windows にインストールされている限りサポートされ、期限は Windows のライフサイクルに従う
- 4.8.1 が最新版で、今後の Windows リリースにも同梱されるとされています
つまり「.NET 8 が終わるから、.NET Framework も来年終わる」は誤解です。.NET Framework 4.8 / 4.8.1 のアプリを保守しているなら、見るべきは動いている Windows のライフサイクルです。たとえば Windows Server 2022 なら、Microsoft Lifecycle のページでメインストリームサポートの終了が 2026年10月14日、延長サポートの終了が 2031年10月と示されています(同ページは太平洋時間表記なので、日付の境目を厳密に扱う場合は原典を確認してください)。
ただし、古い .NET Framework には個別の期限があります。
- .NET Framework 4.6.2 のサポート終了は 2027年1月12日
- .NET Framework 4.5.2 / 4.6 / 4.6.1 は 2022年4月26日に終了済み
4.6.2 を使っているなら、2027年1月12日という別の期限が視界に入っているということです。この場合の対応は「4.8 / 4.8.1 に上げる」か「.NET へ移行する」かの判断になります。
もうひとつ、Xamarin は 2024年5月1日に全 SDK のサポートが終了済みです(Xamarin.Forms を含む)。公式は .NET MAUI への移行を案内しています。Xamarin 案件を抱えている場合は、.NET 8 / 9 の期限より前に、そちらのほうが優先度が高いはずです。
移行作業の見積もり:自分の時間を原価として計算する
受託でこの移行をやるなら、見積もりの根拠が要ります。「.NET 10 に上げます、◯円です」では通らないので、作業を分解して積むことになります。
この記事の6ステップは、そのまま見積もりの項目にできます。
- STEP1 TFM 変更とビルド通し
- STEP2 NuGet パッケージの棚卸しと更新(EF Core を使っているなら、ここが厚くなる)
- STEP3 警告の解消
- STEP4 破壊的変更の影響調査
- STEP5 動作確認・テスト
- STEP6 本番反映とロールバック準備
規模も構成もプロジェクトごとに違うので、この記事で「◯時間」という数字は出しません。代わりに、自分の1時間の値段を先に決めておくことをおすすめします。時間単価が決まっていないと、「調査に3時間かかった」が高いのか安いのか判断できず、見積もりが感覚頼りになります。
希望月収から逆算した時給は、このサイトのツールで出せます。移行作業のように「作業量が読みにくい仕事」ほど、単価×想定時間+調査バッファという形で組み立てると説明しやすくなります。
なお、移行の検証を本番と同じ Windows 環境でやりたいが手元に用意できない、というケースもあります。特に WinForms / WPF のように Windows でしか確認できないものは、検証用の環境をどうするかが地味に効きます。手元の PC を壊さずに別の Windows を用意する方法はクラウドPC(仮想デスクトップ)の記事に、料金や契約条件も含めてまとめてあります。Mac で C#/.NET を開発している場合はMac での開発環境の記事のほうが近いはずです。
まとめ:期限は動かないので、判断だけ先に済ませる
- .NET 8(LTS)と .NET 9(STS)のサポートは 2026年11月10日に終了。STS が18ヶ月から24ヶ月に延びた結果、同じ日になりました
- その日にアプリが止まるわけではありません。止まるのはセキュリティ更新と技術サポートです
- 移行先は .NET 10(LTS・2028年11月14日まで・C# 14)。LTS から LTS なので比較的素直な移行です
- 手順は TFM 変更 → NuGet 確認 → 警告 → 破壊的変更 → 動作確認 → 本番反映の6ステップ。EF Core を使っているなら、EF Core 10 は .NET 10 が必須という点が最大の分岐
- 「移行しない」も条件つきで成立する判断です。ただし期限を知ったうえで選ぶこと
- .NET Framework 4.8 / 4.8.1 は別ライフサイクル(Windows のコンポーネント)。ただし 4.6.2 は 2027年1月12日という別の期限があります
まず dotnet --list-runtimes と .csproj の <TargetFramework> を見るところから。数分で「自分は対象か」だけは分かります。そこから先の判断は、この記事の判断フローを使ってください。
C#/.NET でデータベースを扱う具体的な手順・使い分けは、ハブ記事にまとめています。移行後の動作確認の観点でも役に立つはずです。

【PR】移行のような「レガシー保守・バージョンアップ」の仕事が、実際にどんな条件で募集されているかを見ておくと、単価を考えるときの参考になります。報酬・条件の最新情報は公式サイトで確認してください。
フリーランスエンジニア向け案件検索サイト【フリーランスボード】【PR】移行の動作確認用に、Windows 環境を手元以外に用意する選択肢もあります。ただし WinForms / WPF の動作確認のような中小規模の検証用途向けで、大規模ソリューションを常用する開発機の代わりにはなりません。最低利用期間や、無料トライアル終了後に本契約へ自動で移行する条件があるため、申し込み前に必ず公式サイトで確認してください。
仮想デスクトップサービス『XServer クラウドPC』- .NET 8 のサポート終了日はいつですか?
-
2026年11月10日です。.NET 8 は LTS(Long Term Support)としてリリース日(2023年11月14日)から3年間サポートされ、その期間がこの日に終わります。同じ日に .NET 9(STS・2024年11月12日リリース)もサポート終了を迎えます。.NET 9 は STS のサポート期間が18ヶ月から24ヶ月に延長されたため、結果として .NET 8 と同じ日になりました。移行先の .NET 10 は LTS で、2028年11月14日までサポートされます(2026年8月20日に .NET 公式サポートポリシーで確認)。
- サポートが終了すると、アプリは動かなくなりますか?
-
動かなくなるわけではありません。Microsoft の説明でも、サポート終了後もアプリケーションは動作し続けるとされています。終わるのは新しいセキュリティ更新の提供と技術サポートです。そのため「動いているから大丈夫」と放置すると、修正されない脆弱性を抱えたまま運用する状態になります。外部に公開しているアプリや、クライアントに納品したアプリは、期限内の移行を優先するのが安全です。
- .NET 8 から .NET 10 への移行は大変ですか?
-
LTS から LTS への移行なので、.NET Framework から .NET への移行に比べれば素直です。基本の流れは「
<TargetFramework>をnet10.0に変える → NuGet パッケージの対応を確認する → ビルド警告を潰す → 破壊的変更を確認する → 動作確認 → 本番反映」の6ステップです。ただし規模と構成によって作業量は大きく変わります。特に EF Core を使っている場合、EF Core 10 はターゲットフレームワークが .NET 10 なので、.NET 10 への移行とセットになります。破壊的変更の一覧は Microsoft Learn の互換性ページで、自分が使っている領域だけ確認してください。 - .NET Framework 4.8 も 2026年11月に終了しますか?
-
いいえ、別のライフサイクルです。.NET Framework は 4.5.2 以降、Windows のコンポーネントとして定義されており、親となる OS と同じサポートを受けます。.NET Framework 4.8 と 4.8.1 には個別のサポート終了日が設定されておらず、サポート対象の Windows で動いている限りサポートされます。ただし.NET Framework 4.6.2 は 2027年1月12日にサポート終了、4.5.2 / 4.6 / 4.6.1 は 2022年4月26日に終了済みです。古いバージョンを使っている場合は、そちらの期限を確認してください。
- 移行しないという判断はありですか?
-
条件つきで成立します。オフラインや閉じたネットワークでしか動かない社内ツール、すでに使われていないアプリなどは、期限に追われて壊すより現状維持のほうが合理的なこともあります。ただし、期限を知ったうえで選ぶこと、セキュリティ更新が来ない前提で運用範囲を限定すること、依存パッケージの更新も止まっていく前提を持つこと、再開するときは移行から始めると決めておくことが条件です。外部公開しているものや納品したものについては、期限内の移行を検討してください。
出典・参考
いずれも 2026年8月20日に確認しました。
- .NET 公式「.NET and .NET Core Support Policy」(各バージョンのリリース日・LTS/STS・サポート終了日、毎年11月リリースの方針):https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core
- .NET Blog「.NET 8 and .NET 9 will reach End of Support on November 10, 2026」(終了後もアプリは動作するがセキュリティ更新は提供されない・STS が18→24ヶ月に延長・アップグレード手段の案内):https://devblogs.microsoft.com/dotnet/dotnet-8-9-end-of-support/
- Microsoft Learn「Breaking changes in .NET 10」(破壊的変更の分類と領域別一覧。同ページに「作成中・完全な一覧ではない」の注記あり):https://learn.microsoft.com/en-us/dotnet/core/compatibility/10.0
- Microsoft Learn「EF Core releases and planning」(EF Core 10 のターゲットは .NET 10・EF Core 9 / 8 のサポートは2026年11月10日まで・メジャー更新には破壊的変更が多い):https://learn.microsoft.com/en-us/ef/core/what-is-new/
- Microsoft Learn「dotnet package list command」(.NET 10 で名詞が先の形を導入・.NET 9 SDK 以前は
dotnet list package・--vulnerableは SDK 9.0.300 以降):https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-package-list - Microsoft Learn「.NET Upgrade Assistant Overview」(同ツールは正式に非推奨・GitHub Copilot の modernization チャットエージェントを案内):https://learn.microsoft.com/en-us/dotnet/core/porting/upgrade-assistant-overview
- Microsoft Learn「Configure language version(C# reference)」(TFM より新しい C# 言語バージョンはサポートされない・
LangVersionをlatestにしない):https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/configure-language-version - Microsoft Learn「The history of C#」(C# 14 は2025年11月リリース):https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-version-history
- .NET 公式「.NET Framework Support Policy」(4.5.2 以降は Windows のコンポーネント・4.8 / 4.8.1 に個別の終了日なし・4.6.2 は2027年1月12日終了):https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-framework
- Microsoft Lifecycle「Windows Server 2022」(メインストリーム終了2026年10月14日・延長終了2031年10月/太平洋時間表記):https://learn.microsoft.com/en-us/lifecycle/products/windows-server-2022
- .NET 公式「Xamarin Support Policy」(2024年5月1日に全 Xamarin SDK のサポート終了):https://dotnet.microsoft.com/en-us/platform/support/policy/xamarin
- NuGet「Dapper」(2026年8月20日時点の最新版 2.1.79・対応ターゲット):https://www.nuget.org/packages/Dapper
- NuGet「Npgsql」(同 10.0.3・対応ターゲット):https://www.nuget.org/packages/Npgsql
- NuGet「Microsoft.Data.Sqlite」(同 10.0.11・対応ターゲット):https://www.nuget.org/packages/Microsoft.Data.Sqlite
- NuGet「SqlKata」(同 4.0.1・対応ターゲット):https://www.nuget.org/packages/SqlKata
