2013-11-23 1 views
5

私はおそらくかなり一般的な問題に直面していますが、私はそれに対する解決策を見つけることができません。 問題は、ユーザーがクライアント上のキャッシュにエンティティを持ち、別のユーザーが(サーバー上の)エンティティの一部を削除した場合に発生します。第1のユーザがそのデータを更新したいとき、除去されたエンティティはキャッシュから除去されない。更新するたびにキャッシュをクリアすることで解決できますが、保存されていない変更もすべて失われます。 明白なものがありませんか?Breeze:キャッシュ全体をクリアせずに、別のユーザーがデータベースから削除したエンティティをキャッシュから削除しますか?

例:

モデル:

public class Order 
{ 
    [Key] 
    public int Id { get; set; } 
    public ICollection<OrderDetail> OrderDetails { get; set; } 
} 

public class OrderDetail 
{ 
    [Key] 
    public int Id { get; set; } 
    [ForeignKey("Order")] 
    public int Order_Id { get; set; } 
    public virtual Order Order { get; set; } 
} 

クライアントコード:

function getOrder(orderId, orderObservable) { 
    var query = EntityQuery.from("Orders") 
       .where("orderId", "==", orderId) 
       .expand("orderDetails"); 
    return manager.executeQuery(query).then(querySucceeded).fail(queryFailed); 

    function querySucceeded(data) {    
     var order = data.results[0]; 
     // NOTE: the removed orderdetail is still there 'order.orderDetails' 
     orderObservable(order); 
    } 
} 

ステップバイステップシナリオ:

  1. ユーザAの問合せその付き注文の対応する注文詳細。
  2. 注文と発注明細はキャッシュに入れられます。
  3. ユーザーBはorderdetailを削除し、変更をサーバーに保存します。
  4. ユーザー注文の最新の更新を取得するためのクエリ。
  5. クエリが削除されたorderdetailを返すとき、まだそこにあります。

breeze-docsでは、「キャッシュのクリアに関する重要な注意事項」の下に、キャッシュとクエリの結果を比較してキャッシュされたエンティティを削除し、欠落したエンティティを結果から切り離すソリューションがあります。 http://www.breezejs.com/documentation/entitymanager-and-caching しかし、この場合は動作しません。私はorderdetailsがオーダーに関連しており、成功コールバックに渡される前にキャッシュから "ピックアップ"されているという事実と関係があると推測しています。

すべてのご協力ありがとうございます。

+0

これを試してください:http://blogs.msdn.com/b/diego/archive/2012/04/01/tips-to-avoid-deadlocks-in-entity-framework-applications.aspx –

答えて

3

あなたが直面している問題は、Breezeではなく一般的な設計です。頭に浮かぶのオプションがいくつかあります -

  1. 使用SignalRキャッシュから任意の削除エンティティを取り外し、変更が発生したWebアプリケーションを通知します。

  2. エンティティをデータベースから削除する代わりに、アーカイブ済みまたは削除済みのフラグを使用してください。

どちらも長所と短所があります。 SignalRで

あなたは、通知のための場所での配管作業を取得し、削除し、削除するエンティティ

manager.detachEntity(entityToDetach); 

あなたが代わりに削除切り離しう理由で周りの特定の作業の流れを設定する必要がありますので、あなたはそれを設定した場合、削除すると、Breezeエンティティマネージャは引き続きその変更をデータベースに保持する必要があると考えます。

あなたはフラグを使用する場合、あなたは、単に削除またはアーカイブとしてフラグ付けされたエンティティを無視するように、あなたのビジネスロジックを設定することができ、あなたがDBを照会するとき、それはそのエンティティへの変更を返し、それを

myEntity().archived(true); 
の表示を停止します

エンティティがクエリと一致しない場合、更新されたエンティティがクライアントにアーカイブまたは削除されたことを知らせることはありません。もう1つの注意点は、データベース内に情報があり、もはやアクティブではないということです。

あなたが持っているアプリケーションと要件の種類によって、これらの選択肢の1つを選択するか、別のものを提示する必要があります。希望が役立ちます。

関連する問題