Question

gens bien, je suis un nouveau venu aux services de données et LINQ désespérément besoin de quelques conseils. Dans quelques jours, j'ai rencontré de nombreux obstacles inattendus et je suis coincé sur un maintenant. J'espère que ce sont des frustrations juste typiques de l'apprentissage d'un nouvel outil.

J'ai un service de données WCF pour servir des données à partir d'une table de base de données Sql Server des coordonnées GPS. En particulier, j'ai une méthode d'opération de service qui vous permet de spécifier une précision décimale et plage latitude / longitude pour produire une représentation plus générale des données.

Dans un navigateur Web, il semble fonctionner comme prévu. Cependant, lorsque je tente d'appeler l'opération de mon application cliente, la liste retournée au client diffère de la liste générée par le service.

Je vais utiliser des morceaux de mon code pour expliquer les détails:

Opération Service de données:

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

Si je déboguer la méthode précédente (en cours d'exécution sur le serveur virtuel de Visual Studio) lorsqu'il est appelé à partir de mon application client, gpsList semble contenir les données appropriées juste avant de retourner au client. En utilisant mes paramètres de test, je reçois une liste de 200 objets distincts dont les valeurs GPS sont arrondies aux décimales je précise.

Cependant, une fois que les résultats sont renvoyés à la méthode d'appel dans mon application client, j'ai une liste de 200 objets GPS, mais ils sont tous la même valeur. Pour être précis, la valeur dupliquée est la dernière valeur dans mon jeu de résultat attendu. Je confirme en appelant cette opération dans un navigateur Web et l'affichage des résultats.

Méthode client:

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

J'ai essayé de retirer le « ToList () » partie de la ligne « Execute () », mais lorsque je tente de voir le jeu de résultats dans le débogueur, il montre une exception qui se lit comme suit: « Une seule énumération est pris en charge par ce IEnumerable. "

Pour autant que je peux dire, mon code client est le premier suspect. Après tout, tous les autres spectacles de test que mon opération de service de données produit les résultats souhaités.

Dois-je besoin de faire quelque chose de différent pour obtenir la liste IEnumerable des objets du service de données?

Je crois comprendre qu'il ya une option CreateQuery (), mais je l'ai lu que execute () est la route la plus appropriée pour ce scénario.

Était-ce utile?

La solution

Il est probablement à cause de cela:

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

Je suppose que la propriété Id de l'entité GPS est votre clé primaire. Dans votre exemple, vous définissez l'identifiant de chaque retour Gps à zéro. Dans la bibliothèque client WCF Data Services, des entités avec la même clé primaire sont traités comme la même instance pour des raisons de suivi des modifications et que des graphes d'objets se comportent comme on peut s'y attendre dans un environnement suivi de référence orienté objet tel que .NET.

Si pour une raison quelconque, vous ne pouvez pas donner les entités Gps un identifiant unique, pensez à utiliser un Guid pour la clé primaire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top