質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Entity Framework

Entity Frameworkは、.NET Framework 3.5より追加されたデータアクセス技術。正式名称は「ADO.NET Entity Framework」です。データベースエンジンに依存しておらず、データプロバイダの変更のみで様々なデータベースに対応できます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

意見交換

クローズ

6回答

1807閲覧

EntityFrameworkでの親子関係保証および重複回避の実現方法

JOE

総合スコア13

Entity Framework

Entity Frameworkは、.NET Framework 3.5より追加されたデータアクセス技術。正式名称は「ADO.NET Entity Framework」です。データベースエンジンに依存しておらず、データプロバイダの変更のみで様々なデータベースに対応できます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

0グッド

0クリップ

投稿2023/03/19 22:47

0

0

C#で、EntityFrameworkを利用したシステムを開発中です。
データベースはSQL Serverです。

親子関係保証について

あるテーブルAとテーブルBが親子関係にあります。Aを親、Bを子とします。
クライアントAでの子レコード追加処理の時に、親子関係保証するための手法としてはどちらが良いでしょうか。

  1. 親テーブルにUPDLOCKをかけてSELECTし、親レコードが存在するか確認する
  2. 子テーブルBに外部キーを作成して、SQL Serverの親レコードなしエラーをハンドリングする。

重複回避について

あるテーブルAにレコードを追加するとき、重複が発生しないようにする手法としてはどちらが良いでしょうか。

  1. テーブルAにTABLOCKXをかけてSELECTし、同一の重複不可項目が登録されていないか確認する。
  2. テーブルAにユニークキーを作成し、レコード追加実行時のSQL Serverのユニーク制約違反をハンドリングする。

どちらの議題についても、SQL Serverのエラーハンドリングで良い気がしますが、ユーザーがわかりやすいメッセージにするには、EntityFrameworkで特定のエラーをハンドリングしないといけないので難しいのでは、と思っています。

ご意見よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

回答6

#1

退会済みユーザー

退会済みユーザー

総合スコア0

投稿2023/03/19 23:06

編集2023/03/20 01:18

質問者さんはどちらも 2 が良いと思っているが、

ユーザーがわかりやすいメッセージにするには、EntityFrameworkで特定のエラーをハンドリングしないといけないので難しいのでは、と思っています。

・・・ということで踏み切れない。それが解決できれば 2 で行きたいと言うことですよね?

であれば、以下の記事のようにしてはいかがですか。

EF Core で PK / Unique 制約違反例外をキャッチ
http://surferonwww.info/BlogEngine/post/2021/03/25/aspnet-core-validation-for-pk-and-unique-restrictions-of-sql-server.aspx


【追記】

「親子関係保証について」の方は、アプリの UI で対応可能なら、ドロップダウンリストから選ばせるという方法が良さそうです。


【追記2】

「親子関係保証について」でドロップダウンリストを使う例を紹介しておきます。

Microsoft のサンプルデータベース Northwind の Products, Suppliers, Categories テーブルを例にとります。

Products テーブルには SupplierID, CatrgoryID というフィールド(下の画像の青枠)があって、Suppliers, Categories テーブルに FK 制約を張ってあります。

イメージ説明

それらのテーブルから EF で使うコンテキストクラスとエンティティクラスを生成すると以下のようになります。

イメージ説明

それをベースに Visual Studio で ASP.NET MVC アプリのコードを自動生成させると、Supplier, Category に対しては以下のようにドロップダウンリストが組み込まれ、リストの項目しか入力できない、すなわち FK 制約違反は起こらないようになります。

イメージ説明

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#2

JOE

総合スコア13

投稿2023/03/20 10:46

#1
SurferOnWww様、回答ありがとうございます。
当方はEF6ではありますが、ご紹介のリンク先に実現方法が出ていましたので、活用しようと思います。
親子関係保証のほうもSqlExceptionにて判定できそうです。
ちなみに、追記2の手法ですが、別のクライアントで、親レコードが先に削除された場合、FK制約違反が発生するのはないかと思うのですが、いかがでしょうか。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#3

退会済みユーザー

退会済みユーザー

総合スコア0

投稿2023/03/20 23:20

編集2023/03/20 23:25

追記2の手法ですが、別のクライアントで、親レコードが先に削除された場合、FK制約違反が発生するのはないかと思うのですが、いかがでしょうか。

#1 の私の回答の「追記2」で、最後に示した画像を表示して作業をしている間に Suppliers, Categories テーブルのレコードが削除されることがあると言ってます?

であれば、Suppliers, Categories テーブルのレコードを削除しようとした時点で FK 制約違反でエラーになって削除はできないはずです。

ただし、FK 制約のフィールドが NULL 不可になっている場合、連鎖削除が設定されると思います。詳しくは以下の記事をみてください。

Code First で外部キープロパティの定義
http://surferonwww.info/BlogEngine/post/2016/09/11/defining-foreign-key-property-in-entity-framework-code-first.aspx

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#4

JOE

総合スコア13

投稿2023/03/21 00:14

であれば、Suppliers, Categories テーブルのレコードを削除しようとした時点で FK 制約違反でエラーになって削除はできないはずです。

Productsテーブルにレコードを追加する前ですよね。Productsテーブルのレコードが0件でも、Suppliers, Categories テーブルのレコードを削除しようとした時点で FK制約違反になるんですか?

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#5

退会済みユーザー

退会済みユーザー

総合スコア0

投稿2023/03/21 02:37

編集2023/03/21 02:38

Productsテーブルにレコードを追加する前ですよね。Productsテーブルのレコードが0件でも、Suppliers, Categories テーブルのレコードを削除しようとした時点で FK制約違反になるんですか?

そういう条件は書いて無かったよね。今さら何言ってるのって感じです。

Microsoft のサンプルデータベース Northwind の Products, Suppliers, Categories テーブルを例にとります。

と書きましたが、それらのテーブルにはレコードは入ってます。もちろん FK 制約の問題がないように。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#6

退会済みユーザー

退会済みユーザー

総合スコア0

投稿2023/03/21 02:44

意見交換というより Q&A なので、質問がある場合は質問としてスレッドを立ててください。その際は開発環境や条件などの情報をきちんと書くようお願いします。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

最新の回答から1ヶ月経過したため この意見交換はクローズされました

意見をやりとりしたい話題がある場合は質問してみましょう!

質問する

関連した質問