Domanda

Va bene gente, sono un nuovo arrivato in Data Services e LINQ e ho un disperato bisogno di una guida.In pochi giorni ho incontrato numerosi ostacoli inaspettati e ora sono bloccato su uno.Spero che queste siano solo le frustrazioni tipiche dell'apprendimento di un nuovo strumento.

Ho un servizio dati WCF per fornire dati da una tabella di database SQL Server di coordinate GPS.In particolare ho un metodo operativo del servizio che consente di specificare una precisione decimale e un intervallo di latitudine/longitudine per produrre una rappresentazione più generale dei dati.

In un browser web sembra funzionare proprio come previsto.Tuttavia, quando provo a chiamare l'operazione dalla mia applicazione client, l'elenco restituito al client è diverso dall'elenco generato dal servizio.

Utilizzerò parti del mio codice per spiegare i dettagli:

Operazione del servizio dati:

    // 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;
    }

Se eseguo il debug del metodo precedente (eseguendolo sul server virtuale di Visual Studio) quando chiamato dalla mia app client, gpsList sembra contenere i dati corretti subito prima di tornare al client.Utilizzando i miei parametri di test, ottengo un elenco di 200 oggetti GPS distinti i cui valori sono arrotondati alle cifre decimali da me specificate.

Tuttavia, una volta restituiti i risultati al metodo di chiamata nella mia app client, ho un elenco di 200 oggetti Gps, ma hanno tutti lo STESSO valore.Per essere precisi, il valore duplicato è l'ULTIMO valore nel set di risultati previsto.L'ho confermato richiamando questa operazione in un browser Web e visualizzando i risultati.

Metodo del cliente:

// 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;
    }
}

Ho provato a rimuovere la parte "ToList()" della riga "Execute()", ma quando provo a visualizzare il set di risultati nel debugger, mostra un'eccezione che dice: "Solo una singola enumerazione è supportata da questo IEnumerable. "

Per quanto ne so, il mio codice cliente è il primo sospettato.Dopotutto, ogni altro test mostra che l'operazione del mio servizio dati sta producendo i risultati desiderati.

Devo fare qualcosa di diverso per ottenere l'elenco di oggetti IEnumerable dal servizio dati?

Capisco che esiste un'opzione CreateQuery(), ma ho letto che Execute() è il percorso più appropriato per questo scenario.

È stato utile?

Soluzione

Probabilmente è per questo:

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

Presumo che la proprietà Id dell'entità Gps sia la tua chiave primaria.Nel tuo esempio stai impostando su zero l'ID di ciascun Gps restituito.Nella libreria client WCF Data Services, le entità con la stessa chiave primaria vengono trattate come la stessa istanza sia per motivi di rilevamento delle modifiche sia in modo che i grafici degli oggetti si comportino come ci si aspetterebbe in un ambiente orientato agli oggetti e con rilevamento dei riferimenti come .NET.

Se per qualche motivo non puoi fornire alle entità GPS un ID univoco, considera l'utilizzo di un Guid per la chiave primaria.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top