2

既存の Breezejs の例はすべて、エンティティ モデルを との間で受け渡ししているようBreezeControllerです。

しかし、構築されたほとんどすべてのページは、何らかの形式のビュー モデルを使用しています。BreezeJ がない時代には、リポジトリからデータ (ドメイン モデル) を取得して、(AutoMapper を使用するか、手動で) ビュー モデルに入力します。ビュー モデルには、そのビューに必要なデータのみが含まれます。WebAPI はビュー モデル データのみをブラウザに送信し、そこでクライアント側のビュー モデル (通常はknockoutオブザーバブル) を設定できます。

データを保存するときは、 からデータを収集し<form>て入力ビュー モデルに入力し、そのデータのみをサーバーに送信します。サーバーでは、入力ビュー モデルのデータがドメイン モデルにマップされます。SaveChanges()更新は、リポジトリ内のDbContextエンティティを呼び出すことによって保存されます。

ではBreezeJsEFContextProvider. 私が見た例では、通常、ドメイン モデル データを取得し、それをすべてクライアント側に渡します。

[HttpGet]
    public IQueryable<Item> Items() {
        return _contextProvider.Context.Items;
    }

ビュー モデルを構築するのは、クライアント側の JavaScript の仕事です。

もちろん、サーバー側でビュー モデルを構築することも可能です。

[HttpGet]
public List<ItemViewModel> Items() {
    var items = _contextProvider.Context.Items
                  .Include("RelatedEntity")
                  .ToList();
    var model = new List<ItemViewModel>();
    .... some code to build model from items ....
    return model;
}

利点は、ネットワーク経由で転送されるデータが少なくなり、サーバー側で多くの操作を実行できることです。しかし、これをそのように変更することが良い習慣であるかどうかはわかりませんBreezeController。しかし、少なくとも、すべてのアイテムを一覧表示するために必要なデータを返します。

POSTデータを戻そうとしたときに、本当の問題が発生しました。

私が見つけた BreezeJs の例では、 を使用しko.observableArray()てすべてのドメイン モデル データを格納していますvm.items。次に、新しいレコードnewItemmanager.createEntityドメイン モデルに組み込まれます。データを検証した後item.entityAspect.validateEntity()newItemがプッシュされvm.itemsmanager.saveChanges()呼び出さSaveChanges()れ、何らかの方法で BreezeController を呼び出します。

    [HttpPost]
    public SaveResult SaveChanges(JObject saveBundle) {
        return _contextProvider.SaveChanges(saveBundle);
    }

あまりにも多くのものが乗っ取られていることがわかりました。(同意しない場合は笑ってください。)私の質問は次のとおりです。

  1. すぐcreateEntityにできますsaveChangesか?記入して送信する空のフォームしかありません。itemsクライアント側でアレイ全体を構築する必要はまったくありません。

  2. 入力ビュー モデルを として渡し、 をJObject呼び出す前にサーバー側の処理を行うことはできます_contextProvider.SaveChanges()か?


またまた超長文になってしまいました。最後まで読んでいただきありがとうございます。心から感謝する!

4

1 に答える 1

5

良い質問です。残念ながら、私たちのデモ コードでは、クライアントとサーバーの両方で Breeze の実際の機能がわかりにくくなっているようです。Breeze は、あなたが恐れる方法で制限されません。

ドキュメントに記載されているすべてのことを繰り返したくありません。私たちは本当にこれらの問題について話します。確認するには、さらに例が必要です。

CQRS 設計について説明しています。ほとんどのアプリケーションは複雑すぎると思います。しかし、それはあなたの特権です。

ItemViewModelの代わりに送信したい場合はItem、送信できます。それを Breeze クライアントでエンティティとして扱いたい場合はEntityManager、KO オブザーバブルに変換してキャッシュで管理し、追跡を変更し、検証します。メタデータを提供する必要があります。サーバーまたはクライアントで。それは Breeze にも当てはまります...そして名前を付けられる他のすべてのシステム (Ember、Backbone など) にも当てはまります。まもなく、サーバー上で任意の CLR モデルのメタデータを簡単に作成できるようになります。それは役立つかもしれません。

ところで、サーバー上のクエリを完全に制御できItemますItemViewModel。どちらに対しても、制限のないクエリを公開する必要はありません。2番目のサンプルクエリのおかげで、それを知っているようです。

コマンド側へ。

あなたが書いた: 「[例] ko.observableArray() を使用して、すべてのドメイン モデル データを格納します。たとえば vm.items としましょう

それは正確には真実ではありません。例にある items 配列は、プレゼンテーション用に存在します。項目配列には、Breeze の観点からは何も格納されていません。実際、クエリの後、クエリの応答で返されたエンティティ (エンティティの場合) は、クエリの結果に対して何をしても、それらを配列に入れるか破棄するかに関係なく、既にマネージャーのキャッシュにあります。マネージャによるエンティティの追跡において、アレイは何の役割も果たしません

あなたはこう書きました:「すぐcreateEntityにできますsaveChangesか?

もちろん!このEntityManager.createEntityメソッドは、新しいエンティティをキャッシュに入れます。繰り返しますが、items配列にプッシュされているのは、ユーザーに提示するためです。その配列は、マネージャーが保存するものとは関係ありません。

あなたは次のように書いています_contextProvider.SaveChanges()

「入力ビューモデル」の意味がわかりません。ブリーズEntityManagerはエンティティを追跡します。「入力ビューモデル」がエンティティの場合、EntityManagerはそれを追跡します。変更されている場合に を呼び出すsaveChangesと、マネージャーはそれをコントローラーのSaveChangesメソッドに送信します。

コントローラーのSaveChangesメソッドの実装を所有しています。JObject変更セット データの JSON.NET 表現にすぎないものを使用して、好きなことを行うことができます。がContextProviderそのオブジェクトを解析してSaveMap. EFContextProvider のカスタマイズに関するトピックをお読みください。ほとんどの人は、これがクライアントの変更セット データをデータ アクセス層に渡す前に検証および操作するために必要なものを提供すると感じています。

代わりに、独自のカスタム DTO を作成して、独自のカスタム コントローラー メソッドに POST したい場合は、先に進んでください。でも電話しないでくださいEntityManager.saveChangesEntityManager.getChanges()エンティティの配列を変更して DTO に呼び出して操作します。すべてを手作業で行うことになります。でも君ならできる。個人的にはもっとやりたいことがあります。

于 2013-03-08T21:10:51.857 に答える