0

データベースに 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
}
4

1 に答える 1

0

この質問には、うまく答えるには依存関係が多すぎます。そのうちの最大のものは、ビジネス ルール全体を適用する予定の場所です。好みの順に、次のように質問する必要があります。ビジネス ルール層はありますか? そうでない場合、独立したデータ アクセス レイヤーはありますか? そうでない場合、データ プロバイダー モデルを使用していますか? そうでない場合は、構成 UI を処理している場所で、この種のことを強制する (または SqlException を処理する) ことを検討しています。

wiki のようなものについては、問題のドメインがすでに十分に制約されているため、おそらく非常に複雑なビジネス ルール エンジンは必要ありません。また、これはほとんど変更されない種類のルールのように聞こえるため、正式なルール レイヤーに分離するのは少しやり過ぎです。そのため、この種の制約をデータ レイヤーまたはデータ プロバイダーに配置することをお勧めします。

たとえば、Linq to Sql を使用している場合、モデルの OwnerId プロパティを、WikiUser テーブルとの関係によって関連付けられた null 非許容のプロパティにすることで、SQL Server で行ったことを反映できます。これにより、OwnerId プロパティが設定されていることが強制され (null 非許容であるため)、探している一意の制約が得られます。

于 2009-08-08T01:15:47.007 に答える