質問のコメント欄で私が聞いた、
スキャフォールディング機能を利用してデータベースの CRUD 操作ができる Controller / View を一式自動生成できますが、その中の Edit アクションメソッドをベースに話ができませんか?
に対して、
Editアクションメソッドをベースとして話をしても大丈夫です。
とのことですのでその方向で回答します。
まず、以下のチュートリアルに従って、その中の 1 ~ 2 まで進めてください。
ASP.NET Core MVC と EF Core - チュートリアル シリーズ
https://docs.microsoft.com/ja-jp/aspnet/core/data/ef-mvc/?view=aspnetcore-6.0
- 開始するには
- 作成、読み取り、更新、削除の操作
上の「2. 作成、読み取り、更新、削除の操作」の「Edit ページを更新する」のセクションで、TryUpdateModelAsync メソッドを使うところがキモです。
それはチュートリアルに書いてあるように "過剰ポスティングを防ぐためのセキュリティのベスト プラクティス" ですが、もう一つ効用があって、質問のタイトルの「フォームの入力値に変更があった場合のみデータの更新処理」を行うことにもなります。
データベースを更新 (UPDATE) するには、エンティティに Modified マークをつけてから、そのエンティティをトラックしているコンテキストに SaveChanges メソッドを適用します。
上の「1. 開始するには」でスキャフォールディング機能を使って生成した Controller のコードでは、フォームの入力値に変更がなくても Modified マークがついてしまいます。
上の「2. 作成、読み取り、更新、削除の操作」のように修正すると、まず以下のコードで DB から当該 id の既存のエンティティを読み取り、
var studentToUpdate = await _context.Students.FirstOrDefaultAsync(s => s.ID == id);
以下の TryUpdateModelAsync メソッドで studentToUpdate の中身を送信されてきたデータ(フォームの入力値)で書き換えます。
if (await TryUpdateModelAsync<Student>(
studentToUpdate,
"",
s => s.FirstMidName, s => s.LastName, s => s.EnrollmentDate))
その際、studentToUpdate の中身と送信されてきたデータが異なる場合は自動的にマークが Unchanged から Modified に変わります。同じなら Unchaged のままです。なので、
await _context.SaveChangesAsync();
では Modified マークがついたフィールドのみ UPDATE される SQL 文が投げられます。全フィールドが Unchanged なら SQL 文は投げられません。
投げられる SQL 文は以下の記事のようにして確認できるのでやってみてください。
EF Core で SQL Server に渡される SQL 文の確認
http://surferonwww.info/BlogEngine/post/2021/02/19/obtain-sql-sentence-generated-by-entity-framework-core.aspx