1

ここで私自身の痛みを生み出したと確信していますが、シナリオで新しいエンティティを作成するためのイベントの正しい順序を理解するのに苦労しています。

私のモデルには、ObjectAObjectBの 2 つのオブジェクトがあり、どちらもBaseObjectから継承されており、明らかにそれぞれに独自の追加プロパティがあります。

私の見解では、ほとんどの情報は同じであるため、ユーザーが作成するオプションを選択できるようにしたいと考えています。そのため、SharedProperty1SharedProperty2 (コレクション ナビゲーション プロパティ)に入力し、A または B オブジェクトが必要かどうかに関するオプションを選択し、最後のオブジェクト固有のプロパティを持つ最終ページに入力します。

ユーザーがこのオプションを選択するまで、どのエンティティを作成すればよいかわからなかったので、ビューモデルにオブジェクトを作成して、この一時データを処理しました。その一環として、SharedProperty2 (コレクション)に入力しているときに、新しいChildObjectsを追加するときに、entityManager.createEntity('ChildObject'). 最後に達したら、ObjectAまたはObjectBエンティティを作成し、子エンティティ (およびその他のプロパティ) を追加してから、保存を試みます。

問題は、正しく保存されないことですが、どのアプローチを採用するかによって異なる結果が得られます。ユーザーは新しいオブジェクトのプロセスを中止するだけでよいので、私はChildObjectsを作成してEntityState.Detachedいました。この方法で作成されたすべてのエンティティが id キー 0 を取得することに気付きました。そのため、 ChildEntitesを親 ( ObjectAまたはObjectBのいずれか) に追加しているときに、減少する負の数 (つまり: -1) を割り当てることによってキーを修正しました。 、-2 など)。これにより、一部のエンティティのみがデータベースに保存され、外部キーが競合するという苦情が発生するなど、サーバー側の動作がおかしくなりました。

これもよくわからず汚してしまった悪臭がした。だから今、私はエンティティを通常どおりに作成しようとしました(つまり、Detachedフラグなしで)、それらはすべて独自の一意のキーを取得します(再びそよ風が-1、-2などに続くように見えます)が、今からそれらをコピーしようとすると一時的なビューモデル コレクションを親オブジェクト コレクションに追加すると、an entity with this key is already attached. そのため、保存する正しいモデルを構築することさえできません。

これを処理する方法をまだ正しく理解していないと思うので、いくつかの指針をいただければ幸いです。


私が疑問に思っていることを回避するために、破棄されるエンティティを処理するために RejectChanges を使用しなかった理由を説明します。基本的に、ユーザーは ChildObject (オブジェクトは、breeze entityManager によって作成され、viewmodel コレクションに追加され、UI にバインドされます) を追加し、データを保存する前に、それを再度削除することを決定できます (現在は、viewmodel コレクションから削除されるだけです)。変更の拒否を使用した場合、他の重要なエンティティを破棄します。誰かがビューで ChildObject を削除した場合、私は今、良い子になり、適切な detach メソッドを使用すると思います。

4

1 に答える 1

2

あなたの質問を正しく理解できれば、いくつかのプロパティを作成し、保存時にそれらを親オブジェクト コレクションに追加しようとしています。私が間違っている場合は訂正してください。Breeze はこれをサポートするだけでなく、非常に効率的にサポートします。.NET と C# から来た私にとって、これがどれほど簡単かを理解するのは非常に困難でしたが、私があなただったら、これを行うでしょう -

var childA = ko.observable();
var childB = ko.observable();

childA(entityManager.createEntity('ChildObject')); // populate your children
childB(entityManager.createEntity('ChildObject')); // populate your children

次に、ビューでそれらを編集し、保存する準備ができたら、それらをコレクションに追加するだけです。

var save = function() {
    isSaving(true);
    var parent = ko.observable();
    return entityManager.getParent(parent, parentId)
            .then(setParents)
            .fail(catchError);

    function setParents() {
        childA().parent(parent());
        childB().parent(parent());
        entityManager.saveChanges()
                .then(complete)
                .fail(catchError);

        function complete() {
            isSaving(false);
            return Q.resolve();  // Don't know if you have any unresolved conflicts
        }
    }  
};

基本的にこのように私たちは -

A : エンティティの作成 B : 変更を行わずに編集 C : save を呼び出すと、親ナビゲーション プロパティが設定されます。私の以前の方法では (正しいか間違っているかに関係なく)、単純に ParentId(parentId) を設定し、EF にナビゲート方法を理解させていましたが (駄洒落を許してください)、これは Breeze では簡単です。親オブザーバブルを簡単に渡すこともでき、マネージャーから取得する必要はありません。それは、既に持っているかどうかに依存します。

エンティティを個別に管理したい場合にこれを行う別の方法は、エンティティの準備ができたら、entityManager.saveChanges([childA]) を使用して一度に 1 つのエンティティを保存することです。保存する単一のエンティティを含む配列を渡すだけです。これは、複数のエンティティで作業しているが、すべてを保存する準備ができておらず、アプリ内を移動する必要がある場合に便利です。cancelChanges() を呼び出さない限り、Breeze はエンティティを再度使用する準備ができるまでエンティティをキャッシュに保持します。このように、 isAdded() 状態のエンティティを呼び出すだけで、それらを元に戻して再度編集できます。

于 2013-06-19T13:22:29.740 に答える