6

新しいエンティティのラベルが一意であることを確認する必要があるビュー モデルがあります (まだ DB にはありません)。

現時点では、ビューモデルクラスでそれを行いました:

     public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (PowerOrDuty != null)
        {
            if (PowerOrDuty.Identifier == null)
            {
                using (var db = new PowersAndDutiesContext()) 
                {
                    var existingLabels = db.PowersAndDuties.Select(pod => pod.Label);
                    if (existingLabels.Contains(PowerOrDuty.Label))
                    {
                        yield return new ValidationResult("Cannot create a new power or duty because another power or duty with this label already exists");
                    }
                }                    
            }
           ......

これは小さな DB を使用した小さな内部アプリであり、私の時間は限られているため、コードは完全ではないことに注意してください。

ビュー モデルからの DB アクセスは、よくない方法だと思います。ビュー モデルには直接 DB アクセスが必要ですか? リポジトリを呼び出して利用可能なラベルを取得できるようにする必要がありますか? 代わりに、DB アクセスを必要とする検証をコントローラーで行う必要がありますか?

4

4 に答える 4

6

ビュー モデルには直接 DB アクセスが必要ですか?

これはなんとしても避けるべきだと思います

リポジトリを呼び出して利用可能なラベルを取得できるようにする必要がありますか?

これは ViewModel の問題ではありません。これにより、ViewModel のテストがいくらか複雑になります (ほとんど必要ないはずです)。

代わりに、DB アクセスを必要とする検証をコントローラーで行う必要がありますか?

たぶん、「DB」が「リポジトリ」を意味する場合。しかし、頭に浮かぶのは、別のコントローラーで ajax 検証などのためにプラグイン (アン)、テスト、および再利用できる個別のカスタム検証クラスです。

于 2013-11-08T13:57:40.247 に答える
1

VMからDBにアクセスすることは間違っていないと思います...知る限り、MVCの概念を壊していません(プレゼンテーション層の概念であるため)。サービス層によって提供される Validate メソッドがあれば、もっと良いかもしれません。

ただし、ViewModel のコンテンツに関連するすべてのロジックは、コントローラーよりも VM に保持する方が適切です。よりクリーンなコントローラーの方が優れています。

于 2013-11-08T13:28:36.273 に答える
1

私は個人的に、ViewModel が貧血であることを好みます。つまり、単にプロパティを持つクラスです。

このようなカスタムのサーバー側の検証では、コントローラーでサービスを消費するサービス内で行うか、カスタム バリデーターの背後で行うことをお勧めします。

カスタムバリデーターを使用すると、(オプションで) 検証をリモートで実行することもできます。もう少し複雑になりますが、Ajax アクション メソッドを使用して検証を実行し、それをクライアント バリデーターとリモート バリデーターの両方に接続する汎用リモート バリデーターを使用してそれを行いました (検証ロジックがあることを確認するため)。単一の方法で)。

しかし、いずれにせよ、ViewModel からすべてのロジックを除外する方がより一般的であり、私の意見では、よりクリーンだと思います。単純なアプリであっても、ViewModel はデータベース コンテキストに対して馬鹿げている必要があります。理想的には、サービス (必ずしも Web サービスではなく、抽象化レイヤーのみ) のみがデータベース コンテキストを認識します。

これは、私にとって、アプリケーションのサイズに関係なく行う必要があります。労力と複雑さ (ソリューションに別のアセンブリを追加するだけです) は、得られる抽象化に見合うだけの価値があると思います。将来、別のアプリケーションからサービスを利用することにした場合、またはデータベース コンテキストを交換することにした場合、その抽象化を適切に行うことではるかに簡単になります。

于 2013-11-08T13:33:26.173 に答える
1

ビューモデルはコンテキストに結び付けるべきではありません。データの表示と送信後の検証のみを考慮します。必須フィールドや範囲内の値などの検証を実行できますが、データベースにラベルが既に存在するかどうかはわかりません。

後でラベルをテストするために、フォームを表示する前に「禁止されたラベル」のリストを取得することもできません。これは、そのリストがこの間に変更された可能性があるためです (別のユーザーがデータベースを更新している)。

私の意見では、モデル レベルでの検証は、データ ソースの知識がなくても検証できるものに焦点を当て、一意の制約を持つフィールドに重複した値を送信するなどのエラーをデータベースに通知させる必要があります。このようなエラーのデータベースからの例外をキャッチし、それに応じて管理します。

とにかく、このような問題に対する簡単な答えはないと思います。

于 2013-11-08T13:33:44.740 に答える