2011-03-10 22 views
0

私は、イベントハンドラで実行する2つの同様の、しかし異なるOdataサービス操作呼び出し(同じサービス操作、異なるパラメータ)を持っています。コードを実行すると、各クエリのCreateQuery <>呼び出しが異なるクエリURIを生成し、ブラウザを介して要求されたときに返される結果が正しいことがわかります。 WEIRD STUFFに今すぐ! MergeOption = OverwriteChangesを指定しない限り、2番目のクエリは常に最初のクエリと同じ結果を返します。ここにSVC操作を呼び出す方法の簡略図を示します。WCFデータサービスのMergeOption

List<Listing> whereToDine = Container.CreateQuery<Listing>("SearchListings")       
               .AddQueryOption("listingTypeIds", "'14'") 
               .AddQueryOption("cityId", CityId.ToString()) 
               .AddQueryOption("radius", SearchRadius.ToString()) 
               .AddQueryOption("skipIndex", "0") 
               .AddQueryOption("pageSize", (PageSize * NumPages).ToString())                   
               .AddQueryOption("sortType", "'name'").ToList<Listing>(); 

これはなぜ起こっているのですか?

答えて

1

クライアントはエンティティの追跡を行います(リストがエンティティタイプであると仮定します)。したがって、コンテナ(DataServiceContext)は、クエリの評価時に返されるすべてのエンティティへの参照を保持します。

これは、エンティティの変更を追跡できるようにするために必要です。そのため、SaveChangesを呼び出すときに、エンティティが更新するサーバーに要求を送信する必要があることがコンテキストで分かります。

現在、クライアントはプロパティレベルのトラッキングを実行しないため、エンティティ全体が変更されたかどうかのみを知ることができます。その上の単一のプロパティが変更された場合ではありません。

結果として、サーバーからのデータを読み込み、クライアントが既に追跡しているエンティティが応答に含まれている場合は、サーバーからのデータが使用するものであるかどうかを判断する必要があります。 (基本的に同じエンティティの2つのバージョン、クライアントからのもの、サーバーからのもの)が使用されます。

MergeOptionは、この場合の処理​​をクライアントに指示する設定です。

デフォルトでは、クライアントの値が変更された場合、クライアントの一部の値を変更した場合、サーバーのものがSaveChangesを通じてコミットするまで変更内容を上書きしないようにします。

サービスオペレーションへの最初の呼び出しでは、クライアントはサーバーからエンティティを取得します(最初に)結果が得られます。 2番目の呼び出しでは、おそらく同じエンティティを取得しますが、その中に新しい値があります。しかし、クライアントのデフォルト設定では、クライアントの値を維持するため、クエリの評価によってサーバーからの受信データが効果的に削除されます。

MergeOptionは、クライアントに何をすべきかを伝える正しい方法です。

関連する問題