8

MVC/EF の関係全体を理解しようとしています。データベースとのみ対話するエンティティ モデルを作成する場合 (エンティティ モデルをビューに渡すべきではないため)、次にモデルのクラス、最後にビュー モデルをすべて以下に示します。私の唯一の質問は、2 番目のクラスを持つことは冗長に思えることです。私が見た例で唯一の違いは、ビューと対話しているため、そのクラスにデータ注釈を適用することです。エンティティ オブジェクトがビュー レイヤーで公開されていないことを確認することがなぜそれほど重要なのですか?

私はまだ実際にプロジェクトを書き始めていませんが、エンティティ モデルを使用してデータベースとやり取りし、それを ProductModel にキャストしてビューに渡すと仮定すると、これは正しいロジックですか?

エンティティ モデル:

public class Product 
{
    [Key()]
    public int ID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public double Price { get; set; }
}

モデル:

public class ProductModel
{
    public int ID { get; set; }
    [StringLength(50)]
    [Required(ErrorMessage = "Product Name is required.")]
    [Display(Name = "Product Name")]
    public string Name { get; set; }
    public string Description { get; set; }
    public double Price { get; set; }
}

ビューモデル:

public class ProductViewModel
{
    Product myProduct { get; set; }\
    //Plus any other properties I may need for the view.
}

アップデート:

私が読んでいる例では、次のように DBContext も設定されています。それでは、ProductModel クラスは役に立たないのでしょうか?

public class MyAppContext : DbContext
{
    public MyAppContext()
        : base("name=DBConnection")
    { 
    }

    public DbSet<Product> Products { get; set; }

 }
4

7 に答える 7

3

特に単純なモデルでは、ビュー モデルが必要ない場合があります。しかし、大きな「しかし」ですが、そのような状況のインスタンスはほとんど見つかりませんでした。それでも、後で戻ってビューモデルを作成する必要があることがわかりました。特殊なビューモデルを持つことは、より安全でシンプルで簡単です。

余分な作業と見なすかもしれませんが、関心の分離という観点から考えてください (これが MVC の要点です)。たとえば、入力の SelectList を表示する場合は、それを ViewBag またはモデルに追加できます。ViewBag に追加すると、決して理想的ではない厳密な型付けが失われますが、データベースで追跡されるエンティティにも属しません。ビュー モデルを使用することで、この情報を本来あるべき場所に正確に配置できます。つまり、ビューを提供し、ビューを提供するためだけに存在する厳密に型指定されたモデルです。

または、検証を検討してください。データベースに必須のフィールド (null 以外) が必要であるが、これをユーザーのオプションにし、ユーザーが指定しないことを選択した場合は、舞台裏で自分でビジネス ロジックを入力したい場合はどうすればよいでしょうか。 . ビューモデルはその抽象化を簡単に処理できますが、それをエンティティ自体に追加すると、非常に複雑なレイヤーが追加されます。

もちろん、何も必要ありません。プロジェクトはいつでも好きなように設定できますが、ベスト プラクティスがベスト プラクティスであるのには理由があります。あなたと同じような開発者は、何度も同じ問題に遭遇し、実行可能な解決策をまとめています。しばらくの間はビュー モデルを回避できるかもしれませんが、最終的には同じ障害に遭遇し、とにかくそれらを組み込むことになります。

于 2013-03-28T19:17:31.507 に答える
1

が必要Product classですProductViewModel classDbContext初めてこれを行う場合は、Pro ASP.NET MVC 3 フレームワーク、第 3 版をお読みください。

また

プロ Asp.Net Mvc 4

それらには MVC に関する詳細な情報があり、両方の本にはReal Application tutorial you can follow展開を含む最初から最後まで含まれています。

また、単体テストや、依存性注入 (Ninject) や Moq などのその他の MVC ツールについても学びます。

于 2013-03-28T18:28:21.567 に答える
1

エンティティとは別にモデル クラスを作成する主な理由は 2 つあります。

  1. おっしゃる通り、属性です。いくつかのアプリケーションでエンティティを再利用したい場合がありますが、それらは同じ属性を使用しない場合があります。これらでエンティティを汚染したくありません。

  2. それらの ORM によっては、エンティティに基本クラスが必要になる場合があります。または、エンティティに適用する必要がある属性やその他のカスタマイズがある場合もあります。これにより、ビジネス ロジックをテストするときに問題が発生する可能性があります。さらに、ORM を変更したり、ORM 内の何かを変更した場合、その変更をアプリケーションの残りの部分から分離したままにします。

基本的に、アプリケーションのさまざまなレイヤーを分離し、あるレイヤーを別のレイヤーで行われた変更から保護します。

于 2013-03-28T18:26:28.433 に答える
1

上記の回答に加えて、不要なデータがビュー/クライアントに送信されるのを防ぐために言及されていない別のポイントがあります。

たとえば、製品モデルに、製品を購入するためにサプライヤに支払う価格が含まれているとします。顧客にこのデータを見せたくありませんが、ビューに送信されたモデルに含まれていれば、そのフィールドを表示しなくても顧客はそれを評価できます。これは、別のビュー モデルを使用し、データをビューに送信する前に ef/データベース モデルからビュー モデルにコピーする場合です。

場合によっては、DBcontext クラス、EF/データベース クラス/モデル、およびそれぞれがデータベース モデルからのデータの異なるサブセットを保持するいくつかのビューモデルになることがあります。

また、複数のデータベース モデルからのデータを保持するビューモデルを使用することもできます。これは、ビューがビューバッグでリスト オプションを送信する代わりにリストまたはドロップダウンを使用する場合によく見られます。

于 2013-03-28T18:39:04.597 に答える
1

ViewModel は、実際にブラウザーとの間でやり取りされるものになります。その場で更新/保存できるものを構築している場合は、JSON を介して行われることがよくあります。そう:

  • ASP.Net MVC には、JSON を介して生成/消費できるものに関していくつかの制限があります (その制限は各方向でわずかに異なります)。ViewModel を使用してそれを回避できます

  • データベースからプルバックするデータのサイズは、ブラウザに取得する必要があるサイズではない場合があります。たとえば、いくつかの余分なフィールドをプルバックして、それを渡す前にチェックする必要があるかもしれませんが、サブセットのみを渡したい場合があります。 ViewModel はサブセットです。

  • JSON の一部の自然な構造は、データベースでは実際には使用できません。たとえば、あるテーブルに値があり、別のテーブルに FK があり、ID 、および文字列値 - ただし、ブラウザがそれを利用するには、その文字列値が必要な場合があります。したがって、ViewModel では、単純なディクショナリ (クライアント上で単純な JS オブジェクトになります) ですべてを表します。

  • 多くの場合、日付の書式設定などはクライアントで弱いか、クライアントが正確なシステム クロックを持っているかどうかなどに依存して脆弱です。モデルに DateTime があり、UTC からタイムゾーンと形式に変換する ViewModel で文字列を頻繁に使用します。ブラウザに到着する前に、サーバー上で適切に処理されます。

  • モデルの一部をブラウザに公開しないようにする必要がある場合があります。たとえば、一部のシステムでは、行 ID をブラウザーに公開すると、セキュリティ リスクが生じる可能性があります。ViewModel を使用すると、モデルの一部を簡単に非表示にできます。

参照: ViewModel の設計方法

于 2013-03-28T23:54:02.007 に答える
0

まず、何かが欠けていて、組み合わされたテクニックがあります。1 つは、他のすべてのレイヤーから DAL を完全に抽象化することです。これがテクニックです。しかし、使用できる他のテクニックもあります。「エンティティ」クラスをドメイン クラスとして使用します。単純なシナリオでは、ビジネス レイヤーのドメイン クラスを常に使用して、すべてのビジネス ルールを適用します。これは、多くのコード行/クラス数を増やすことなく、レイヤーを介してテスト容易性を結合し、レイヤー間の不要なリンクを回避するのに大いに役立ちます。

また、このドメイン オブジェクト (ドメイン クラス) をすべてのレイヤーに配置するこのアプローチにより、MVC を使用する場合に作業が大幅に容易になります。

  1. 検証用のビュー
  2. 完全性のためのデータベース

また、このタイプのクラスの概念と使用法を理解するには、注意を払う必要があることがあります。エンティティおよびドメイン クラスとして POCO を使用している場合、これと同じクラスは、DB へのクエリを解釈するときに Entity Framework が使用するクラスとは異なります。代わりに、EF は、そのドメイン オブジェクトをエンティティとして表す動的クラス (POCO から派生) を作成し、すべての仮想フィールド (通常は関連するエンティティ) を読み込みます。

そして、クラスのコードと簡単な再マッピングを保存します。

お役に立てれば

于 2013-03-28T23:33:24.117 に答える
-1

エンティティ オブジェクトがビュー レイヤーで公開されていないことを確認することがなぜそれほど重要なのですか?

そうではありません。単純な CRUD コントローラーの場合、多くの場合、エンティティ オブジェクトを渡すだけの方が簡単です。より複雑なページでは、同時に複数の Entity オブジェクト/タイプとやり取りする場合があります。新しいモデル クラスを作成せずに、両方のオブジェクトに関する情報を渡すにはどうすればよいでしょうか?

于 2013-03-28T18:37:56.527 に答える