4

以下は私のコードです。確認してください。

 1. bool isUnavailable = db.Deploys.Where(p => 
     p.HostEnvironmentId == Guid.Parse(host.ID) &&
     p.Status == (int)DeployStatus.Deploying).AsEnumerable().Any();

これは動作します。

次のステートメントは機能しません。

2. bool isUnavailable = db.Deploys.Where(p => 
    p.HostEnvironmentId == Guid.Parse(host.ID) &&
    p.Status == (int)DeployStatus.Deploying).Any();//Error 

例外は

    An exception of type 'System.NotSupportedException' occurred in 
Microsoft.Data.Services.Client.DLL but was not handled in user code
    
    Additional information: The method 'Any' is not supported.


3. bool isUnavailable = db.Deploys.Where(p => 
        p.HostEnvironmentId.ToString() == host.ID &&
        p.Status == (int)DeployStatus.Deploying).AsEnumerable().Any();//Error

例外は

    An exception of type 'System.NotSupportedException' occurred in 
      Microsoft.Data.Services.Client.DLL but was not handled in user code
      Additional information: The expression (([10007].HostEnvironmentId.ToString() == 
"b7db845b-cec4-49af-8f4b-b419a4e44331") And ([10007].Status == 90)) is not supported.

Deploysクラスは、WCFデータサービスのクライアントプロキシクラスに組み込まれているモデルです。「サービス参照の追加」を使用して、WCFクライアントプロキシクラスを作成していました。

しかし、ジェネリックリストに関しては、以下のコードを想定しています。正常に動作します。

4.bool b=servers.Where(d => 
   d.status == (int)Enums.ServerStatus.Deploying ||
   d.status == int)Enums.ServerStatus.Unavailable).Any();

私の質問は

異なるクラスで同じ方法を使用すると、異なる結果が得られるのはなぜですか(方法2と方法4を参照)。

2と3が機能しない理由。

誰かが私を助けてくれることを願っています。ありがとう

4

1 に答える 1

5

LINQには「プロバイダー」の概念があります。異なるデータソースでLINQを操作する場合、データソースに応じて、同一のLINQクエリに対して異なることが発生する必要があります。

たとえば、LINQを使用してデータベースをクエリする場合、LINQクエリをSQLクエリに変換する必要があります。データソースがODataの場合、クエリをURLに変換する必要があります。それぞれに異なるプロバイダーがあり、各プロバイダーはLINQ演算子およびその他の言語構造の異なるサブセットをサポートします。LINQ-to-SQL、Entity Framework、およびLINQ-to-NHibernateは、データベースアクセス用の3つの一般的なLINQプロバイダーです。

あなたのケースでは、OData用のLINQプロバイダーを含むWCFデータサービスを使用しています。ODataではLINQ演算子を表現する方法がないため.Any()、そのプロバイダーを使用したクエリでLINQ演算子を使用しようとすると、例外がスローされます。を使用.AsEnumerable()するということは、基本的に、その時点でOData LINQプロバイダーの使用を停止し、LINQ-to-Objectsプロバイダー(技術的にはプロバイダーではありませんが、概念的には1つと考えることができます)の使用を開始することを意味します。つまり、前.AsEnumerable()に来たものだけがODataクエリに変換され、にDeploy一致するすべてのエンティティが取得.Where()され、それらがすべてクライアントに転送された後、クライアントは.Any()次の数をチェックして実行します。Deploy受け取ったエンティティ。もちろん、そのようなエンティティが多数ある場合、これは悪いことです。サーバー側(おそらくデータベース)が存在するかどうかを確認するだけで、ネットワークを介した不要なデータ転送が発生します。残念ながら、.Any()OData 1.0ではサポートされていません(OData 2.0についてはわかりません)。

また、ODataは.ToString()どちらもサポートしていない可能性があります。構造を直接比較する必要がある場合がありますGuid。つまり、比較するGUID値を含むローカル変数を作成します。

var g = Guid.Parse("b7db845b-cec4-49af-8f4b-b419a4e44331")`

次に、クエリで次のようにGUIDを比較します。

x.HostedEnvironment == g
于 2012-08-26T11:09:16.403 に答える