データベースに 2 つのテーブルがあります。
Wiki
WikiId
...
WikiUser
WikiUserId (PK)
WikiId
UserId
IsOwner
...
これらのテーブルには、1 (Wiki) 対多 (WikiUser) の関係があります。
LINQ エンティティ クラスに次のビジネス ルールを実装するにはどうすればよいですか。
「ウィキには必ず 1 人の所有者が必要ですか?」
次のようにテーブルを更新しようとしました:
Wiki
WikiId (PK)
OwnerId (FK to WikiUser)
...
WikiUser
WikiUserId (PK)
WikiId
UserId
...
これにより制約が強制されますが、所有者の WikiUser レコードを Wiki の WikiUser コレクションから削除すると、醜い SqlException が返されます。これをキャッチして UI で処理するのは難しいようです。
SqlException が生成される前にこのチェックを実行する方法はありますか? データベースを構築するためのより良い方法は? SqlException をキャッチしてより便利なものに変換する方法はありますか?
編集:可能であれば、検証ルールをLINQエンティティクラス内に保持したいと思います。
編集2:私の特定の状況に関する詳細。
私のアプリケーションでは、ユーザーは Wiki からユーザーを削除できる必要があります。現在 Wiki の「所有者」としてフラグが立てられているユーザーを除いて、すべてのユーザーを削除できる必要があります (Wiki には常に 1 人の所有者が必要です)。
私の制御ロジックでは、次のようなものを使用したいと思います。
wiki.WikiUsers.Remove(wikiUser);
mRepository.Save();
そして、壊れたルールを UI レイヤーに転送します。
私がしたくないことはこれです:
if(wikiUser.WikiUserId != wiki.OwnerId) {
wiki.WikiUsers.Remove(wikiUser);
mRepository.Save();
}
else {
//Handle errors.
}
また、コードを自分のリポジトリに移動したくない (ネイティブの Remove 関数を使用しないように指示するものがないため) ため、次のようなコードも必要ありません。
mRepository.RemoveWikiUser(wiki, wikiUser)
mRepository.Save();
これは受け入れられるでしょう:
try {
wiki.WikiUsers.Remove(wikiUser);
mRepository.Save();
}
catch(ValidationException ve) {
//Display ve.Message
}
しかし、これはあまりにも多くのエラーをキャッチします:
try {
wiki.WikiUsers.Remove(wikiUser);
mRepository.Save();
}
catch(SqlException se) {
//Display se.Message
}
また、ビジネスルールチェックを明示的に呼び出すことはお勧めしません (必要になるかもしれませんが):
wiki.WIkiUsers.Remove(wikiUser);
if(wiki.CheckRules()) {
mRepository.Save();
}
else {
//Display broken rules
}