2010-11-03 49 views
4

好吧,我是數據服務和LINQ的新手,急需一些指導。在短短的幾天裏,我遇到了許多意想不到的障礙,現在我陷入了一種困境。我希望這些只是學習新工具的典型挫折。如何在客戶端.NET應用程序中使用WCF數據服務操作?

我有一個WCF數據服務,用於從Gps座標的Sql Server數據庫表中提供數據。特別是我有一個服務操作方法,它允許你指定一個小數精度和緯度/經度範圍來產生更一般的數據表示。

在網頁瀏覽器中,它看起來像預期的那樣工作。但是,當我嘗試從我的客戶端應用程序調用操作時,返回給客戶端的列表與服務生成的列表不同。

我會用我的代碼片段來解釋的細節:

數據服務操作:

// 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對象的列表,但它們都是相同的值。具體而言,重複的值是我預期結果集中的LAST值。我通過在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; 
    } 
} 

我試圖消除「ToList()」中的「執行()」行的部分,但是當我嘗試查看結果在調試器設置,它示出了這是一個例外:「IEnumerable只支持一個枚舉。」

據我所知,我的客戶端代碼首先是可疑的。畢竟,所有其他測試都表明我的數據服務操作正在產生所需的結果。

我是否需要做一些不同的事情才能從數據服務中獲取IEnumerable對象列表?

我知道有一個CreateQuery()選項,但我讀過Execute()是更適合此場景的路線。

回答

1

這可能是因爲這樣的:

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

我認爲GPS的實體的Id屬性是你的主鍵。在你的例子中,你將每個返回的Gps的Id設置爲零。在WCF數據服務客戶端庫中,具有相同主鍵的實體因爲更改跟蹤的原因而被視爲同一實例,因此對象圖的行爲與您在面向對象,引用跟蹤環境(如.NET)中所期望的相同。

如果由於某些原因您無法爲Gps實體提供唯一的ID,請考慮使用Guid作爲主鍵。

+0

感謝您的建議。這實際上超出了我的想法,但我想如果是這樣的話,我的列表在返回之前的這段代碼之後看起來不正確。但我會試一試,讓每個人都知道結果如何。 – 2010-11-03 13:08:43

+0

你是我今天的英雄!我改變了將它從匿名類型轉換爲Gps對象的部分,而不是更改您概述的代碼部分。在此之前,我宣佈「long id = 0;」然後在轉換例程中設置「Id = id ++」,爲每個項目分配一個唯一的Id值。再次感謝! – 2010-11-03 13:38:12

相關問題