1

問題

オブジェクトに対して実行された LINQ クエリによって生成される Uri をトレースしたいと考えていMicrosoft.WindowsAzure.StorageClient.TableServiceContextます。いくつかのプロパティでTableServiceContext拡張するだけです。System.Data.Services.Client.DataServiceContext

私が抱えている問題は、デバッグ モードで開発マシンで Web ロールを実行すると、クエリが Azure Table Storage インスタンスに対して正常に実行されることです (Dev Storage を使用せずにクラウド内の Azure ストレージに接続しています)。結果のクエリ Uri は、Fiddler を使用するか、デバッガーのステートメントにカーソルを合わせるだけで取得できます。

ただし、Web ロールを Azure にデプロイすると、まったく同じ Azure テーブル ストレージ ソースに対するクエリがResourceNotFound DataServiceClientExceptionで失敗します。FirstOrDefault()空のテーブルでの動作に対処する前に、ResoureNotFound エラーが発生しました。これはここでは問題ではありません。

この問題へのアプローチの 1 つとして、Web ロールがデプロイされたときと開発マシンで実行されているときに生成されるクエリ Uri を比較したいと思いました。

質問

FirstOrDefault()メソッドが呼び出されたときに送信されるクエリのクエリ Uri を取得する方法を知っている人はいますか。から返されたを呼び出すことができることはわかっていますが、 が呼び出さToString()れたときに Uri がさらに最適化され、が呼び出されたときに最終的にサーバーに送信されるものではない可能性があるという懸念があります。IQueryableTableServiceContextFirstOrDefault()ToString()IQueryableFirstOrDefault()

誰かが問題に対して別のアプローチをとっている場合、私は提案を受け付けています。式ツリーが最終的に評価されたときに何が起こるかを判断しようとすると、LINQ の一般的な問題のようです。私のLINQスキルはいくらか改善される可能性があるため、ここでも提案を受け付けています。

サンプルコード

public void AddSomething(string ProjectID, string Username) {
    TableServiceContext context = new TableServiceContext();

    var qry = context.Somethings.Where(m => m.RowKey == Username
        && m.PartitionKey == ProjectID);

    System.Diagnostics.Trace.TraceInformation(qry.ToString());
    // ^ Here I would like to trace the Uri that will be generated
    // and sent to the server when the qry.FirstOrDefault() call below is executed.

    if (qry.FirstOrDefault() == null) {
        // ^ This statement generates an error when the web role is running
        // in the fabric
        ...
    }
}

更新と回答の編集

スティーブは書き込み回答を提供しました。私たちの問題は、Azure OS の更新で修正された単一エンティティ クエリでの PartitionKey/RowKey の順序付けの問題について説明しているこの投稿で正確に説明されているとおりでした。これは、開発マシンと、Web ロールが Azure にデプロイされた時期との間の不一致を説明しています。

以前に存在チェックでResourceNotFoundの問題を処理したことを示したとき、コードでは 2 つの方法で処理していました。1 つは例外処理を使用してResourceNotFoundエラーに対処する方法で、もう 1 つは LINQ クエリの最初にRowKeyを配置する方法でした(一部の MS 関係者が適切であると指摘したため)。

例外処理を使用する代わりに、 RowKeyが最初にあった場所がいくつかあることがわかりました。コードをリファクタリングして .NET 4 をターゲットにし、.IgnoreResourceNotFoundException = true property of theTableServiceContext を使用することで、これに対処します。

教訓 (複数回): 風変わりな文書化されていない動作に依存しないでください。

さておき

クエリ Uri を取得できました。それらは異なることが判明しました (ブログ投稿に示されているように)。結果は次のとおりです。

Dev Fabric からのクエリ URI

` https://ourproject.table.core.windows.net/Somethings() ?$filter=(RowKey eq 'test19@gmail.com') and (PartitionKey eq '41e0c1ae-e74d-458e-8a93-d2972d9ea53c')

Azure Fabric からのクエリ URI

` https://ourproject.table.core.windows.net/Somethings(RowKey= 'test19@gmail.com',PartitionKey='41e0c1ae-e74d-458e-8a93-d2972d9ea53c')

4

1 に答える 1

2

私はもう 1 つうまくやることができます...私は問題が何であるかを知っていると思います。:)

http://blogs.msdn.com/b/windowsazurestorage/archive/2010/07/26/how-wcf-data-service-changes-in-os-1-4-affects-windows-azure-table-clientsを参照してください。 .aspx .

具体的には、(以前のゲスト OS ビルドでは) クエリを (PartitionKey 述語の前に RowKey 述語を使用して) 記述した場合、結果としてフィルター クエリが生成されました (逆に、PartitionKey が RowKey の前にある)。結果セットが空の場合に例外が発生する種類のクエリが発生しました。

上記のブログ投稿に示されているように、適切な修正は、コンテキストで IgnoreResourceNotFoundException を true に設定することだと思います。

于 2010-07-27T04:33:06.897 に答える