3

アプリケーションでかなり標準的なシナリオを考えると、追加/編集/削除できるエンティティのリストがあるとします。最初にページをロードするときに、そよ風でエンティティをクエリします。すべて良い。エンティティを編集すると、そよ風がこれを認識し、エンティティが保存されてキャッシュに更新されるため、リストのあるページに戻ると、アイテムに関連する変更が表示されます。エンティティを削除すると、そよ風の変更が再び保存され、キャッシュが更新されるため、リスト ページに戻ってデータを再クエリしてもエンティティが表示されなくなります (キャッシュからローカルで指摘する必要があります)。

ただし、新しいエンティティを追加すると、リスト ページに表示されません (クエリの要件を満たしていると仮定します)。そのそよ風は、実際にキャッシュをクエリするのではなく、そのクエリに固有のクエリの結果をキャッシュしていると思います(それは理にかなっていますか)?

その場合、キャッシュを完全にクリアするのではなく、特定のエンティティ タイプに関連するキャッシュ アイテムを削除または無効にするように簡単に指示する方法はありますか? 私はいつでもキャッシュのクエリを回避してサーバーに直接アクセスできますが、そよ風がキャッシュに新しく作成されたエンティティを持っていることを知っていると、それは無駄に思えます。

私は多くのクエリに単一のメソッドを使用しているため、そのメソッドでローカルクエリを処理している方法にすぎない可能性があるため、それが原因である場合に備えて以下に含めました。

var defaultQuery = function (observable, resourceName, orderby, where, expand, forceRemote, localEntityName, localCountThreshold, page, count) {
            var query = EntityQuery.from(resourceName);
            if (orderby) {
                query = query.orderBy(orderby);

                if (page) {
                    query = query.skip(pageSize * (page()));
                    query = query.take(pageSize);
                    query = query.inlineCount();
                }
            }
            if (where)
                query = query.where(where);
            if (expand)
                query = query.expand(expand);

            if (!forceRemote) {
                if (localEntityName) {
                    query = query.toType(localEntityName);
                }
                var localResult = manager.executeQueryLocally(query);
                if (localCountThreshold) {
                    if (localResult.length > localCountThreshold) {
                        observable(localResult);
                        return Q.resolve();
                    }
                } else {
                    if (localResult.length > 0) {
                        observable(localResult);
                        return Q.resolve();
                    }
                }
            }

            return query.using(manager)
                .execute()
                .then(function (data) {
                    if (observable) {
                        observable(data.results);
                    }
                    if (count) {
                        count(data.inlineCount);
                    }
                    var logMsg = 'Retrieved ' + resourceName + ' from remote data source with order by {' + orderby + '}, where clause {' + where + '} and expand properties {' + expand + '}';
                    if (page)
                        logMsg += ' for page {' + page() + '} with total record count {' + count() + '}';
                    log(logMsg, data, true);
                })
                .fail(queryFailed);
        };

通常、このような質問では、そよ風がどのように機能するかのいくつかの側面を誤解しているだけなので、誰かが私を修正できる場合は、非常に感謝しています.

ありがとう!


アップデート

私が意図したことをより詳細に示すために、アクションの流れを段階的に含めました。

  1. すべてのオブジェクトに対してクエリを実行
  2. クエリは最初にローカルで実行され、キャッシュ データが存在しないため何も返されません。
  3. 次に、データベースに対してクエリが実行されます - [A,B,C] を返します
  4. A を編集 - AA に名前を変更 - saveChanges() を呼び出します
  5. すべてのオブジェクトに対して同じクエリを実行する
  6. 最初にクエリがローカルで実行され、[AA,B,C] が返されます
  7. 結果がキャッシュから見つかったため、クエリはデータベースに対する実行をスキップします。
  8. B を削除 (setDeleted()) - saveChanges() を呼び出す
  9. すべてのオブジェクトに対して同じクエリを実行する
  10. 最初にクエリがローカルで実行され、[AA,C] が返されます
  11. 結果がキャッシュから見つかったため、クエリはデータベースに対する実行をスキップします。
  12. 新しいエンティティを作成 - 名前を D に設定 - saveChanges() を呼び出します
  13. すべてのオブジェクトに対して同じクエリを実行する
  14. クエリは最初にローカルで実行され、[AA,C] を返します (新しい D オブジェクトは含まれません!)

私が発見しようとしているポイントは、ローカル クエリは、編集と削除のために保存された変更を返すが、追加操作では保存されないということです。Jay が提案したように setDetached を使用してキャッシュからエンティティを削除できましたが、特定のタイプのすべてのエンティティに対して 1 つずつ行う必要があります。それは大きなプロセスかもしれません。


再度更新

私が見た行動は、私の何かの間違いの結果だったようです。結果がそこにあるはずであるというジェイの主張の結果としてすべてを二重および三重にチェックした結果(以下を参照)、「追加された」オブジェクトが表示されるようになりましたが、そもそもそれらを防ぐために何をしたかを正直に説明することはできません.

4

1 に答える 1

3

明確にするために、Breeze はエンティティを編集するとキャッシュを更新します。エンティティはEntityManager.saveChanges()を呼び出すまで保存されません。したがって、「saveChanges」を呼び出すまで、キャッシュとデータベースは異なる状態になります。

EntityManager で既に変更されているエンティティを再クエリすると、サーバー側のデータをクライアント側のキャッシュとマージするアクションがEntityQuery.queryOptions.mergeStrategyによって制御されるという考えの結果が表示されることがあります。デフォルトでは、EntityQuery にはPreserveChangesの MergeStrategy があります。これは、サーバー側の結果がキャッシュ内の「変更された」レコードを上書きしないことを意味します。

投稿の後半で、エンティティの「entityAspect.setDetached」メソッドを呼び出すだけで、任意のエンティティをローカル キャッシュから削除できます。

于 2013-09-16T16:50:14.283 に答える