4

皆さん、私は Data Services と LINQ の新参者であり、何らかのガイダンスがどうしても必要です。ほんの数日で、私は多くの予想外の障害に遭遇しました。これらが、新しいツールを学習する際の典型的なフラストレーションに過ぎないことを願っています。

Gps座標のSql Serverデータベーステーブルからデータを提供するためのWCFデータサービスがあります。特に、小数の精度と緯度/経度の範囲を指定して、データのより一般的な表現を生成できるサービス操作メソッドがあります。

Web ブラウザーでは、期待どおりに動作するように見えます。しかし、クライアント アプリケーションから操作を呼び出そうとすると、クライアントに返されるリストが、サービスによって生成されたリストとは異なります。

コードの一部を使用して詳細を説明します。

データ サービス操作:

    // This is my service operation that I need to call from my client app (see below). 
    // It should return an IEnumerable<Gps> (Gps is one of my Entity Model 
    // types) list of distinct GPS rounded to the number of decimal positions 
    // specified and within the range specified.
    [WebGet]
    public IEnumerable<Gps> GetGpsView(int decimalPlaces, decimal minLatitude, decimal minLongitude, decimal maxLatitude, decimal maxLongitude)
    {
        // I must first return a list of anonymous-type objects
        // because LINQ does not seem to allow me to construct my
        // Gps object within the query (one of those other issues
        // I had to tip-toe around).
        var list = (from g in this.CurrentDataSource.Gps
                    where g.Latitude >= minLatitude &&
                             g.Latitude <= maxLatitude &&
                             g.Longitude >= minLongitude &&
                             g.Longitude <= maxLongitude
                    select new
                    {
                        Id = 0,
                        Latitude = Math.Round(g.Latitude, decimalPlaces),
                        Longitude = Math.Round(g.Longitude, decimalPlaces)
                    }).Distinct().ToList();

        // Now that I have my results, I need to convert the items in the
        // list to my Gps entity object.
        IEnumerable<Gps> gpsList = list.ConvertAll<Gps>(item => new Gps
                            {
                                Id = item.Id,
                                Latitude = item.Latitude,
                                Longitude = item.Longitude
                            });

        return gpsList;
    }

クライアント アプリから呼び出されたときに上記のメソッドを (Visual Studio の仮想サーバーで実行して) デバッグすると、クライアントに戻る直前に gpsList に適切なデータが含まれているように見えます。テスト パラメーターを使用して、値が指定した小数点以下の桁数に丸められた 200 個の異なる Gps オブジェクトのリストを取得します。

ただし、結果がクライアント アプリの呼び出しメソッドに返されると、200 個の Gps オブジェクトのリストが表示されますが、それらはすべて同じ値です。具体的には、重複した値は、予想される結果セットの最後の値です。この操作を Web ブラウザーで呼び出して結果を表示することで、これを確認しました。

クライアント方法:

// Partial class extension of code auto-generated by service reference.
public partial class HsiSideBySideEntities
{
    public List<Gps> GetGpsView(int decimalPlaces, decimal minLatitude, decimal minLongitude, decimal maxLatitude, decimal maxLongitude)
    {
        this.IgnoreMissingProperties = true;

        // Format my relative URI string.
        string uri = string.Format("/GetGpsView?decimalPlaces={0}&minLatitude={1}M&minLongitude={2}M&maxLatitude={3}M&maxLongitude={4}M", decimalPlaces, minLatitude, minLongitude, maxLatitude, maxLongitude);

        // If I debug both client and service at the same time, when I step over this
        // line, it does reach my data service - and as I mentioned above, on the
        // service end it appears to generate the correct results.
        List<Gps> gpsList = this.Execute<Gps>(new Uri(uri, UriKind.Relative)).ToList();

        // However, the results are returned to the client code, my list contains
        // duplicates of the last expected record.
        return gpsList;
    }
}

「Execute()」行の「ToList()」部分を削除しようとしましたが、デバッガーで結果セットを表示しようとすると、「この IEnumerable では単一の列挙のみがサポートされています。 "

私が知る限り、私のクライアント コードが最初に疑われます。結局、他のすべてのテストは、データ サービス操作が望ましい結果を生成していることを示しています。

データ サービスからオブジェクトの IEnumerable リストを取得するには、別の操作が必要ですか?

CreateQuery() オプションがあることは理解していますが、このシナリオでは Execute() がより適切なルートであることを読みました。

4

1 に答える 1

1

これはおそらく次の理由によるものです。

select new
{
    Id = 0,
    Latitude = Math.Round(g.Latitude, decimalPlaces),
    Longitude = Math.Round(g.Longitude, decimalPlaces)
}

Gps エンティティの Id プロパティが主キーであると仮定します。あなたの例では、返された各 Gps の Id をゼロに設定しています。WCF Data Services クライアント ライブラリでは、同じ主キーを持つエンティティは、変更追跡の理由と、.NET などのオブジェクト指向の参照追跡環境でオブジェクト グラフが期待どおりに動作するように、同じインスタンスとして扱われます。

何らかの理由で Gps エンティティに一意の ID を付与できない場合は、主キーに Guid を使用することを検討してください。

于 2010-11-03T01:37:03.937 に答える