Pregunta

gente bien, yo soy un recién llegado a servicios de datos y LINQ en desesperada necesidad de una cierta dirección. Pocos días he encontrado numerosos obstáculos inesperados y estoy atascado en una ahora. Estoy esperando que estos son simplemente frustraciones típicas de aprendizaje de una nueva herramienta.

Tengo un servicio de datos WCF para servir seguridad de los datos de una tabla de datos de SQL Server de coordenadas GPS. En particular, tengo un método de funcionamiento del servicio que le permite especificar un rango de precisión decimal y / latitud y longitud para producir una representación más general de los datos.

En un navegador web que parece funcionar como se espera. Sin embargo cuando intento llamar a la operación de mi aplicación cliente, la lista devuelta a los clientes difiere de la lista generada por el servicio.

Me va a utilizar piezas de mi código para explicar los detalles:

Operación del Servicio de datos:

    // 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 puedo depurar el método anterior (que se ejecuta en el servidor virtual de Visual Studio) cuando se llama desde mi aplicación cliente, gpsList parece contener los datos adecuados justo antes de regresar al cliente. Usando mis parámetros de prueba, consigo una lista de 200 Gps distintos objetos cuyos valores están redondeados a los lugares decimales especifico.

Sin embargo, una vez que los resultados se devuelven al método de llamada en mi aplicación cliente, tengo una lista de 200 Gps objetos, pero todos ellos son el valor MISMO. Para ser más específicos, el valor duplicado es el valor pasado en mi conjunto de resultados esperado. Confirmé esto llamando a esta operación en un navegador web y ver los resultados.

Método 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;
    }
}

I intentado eliminar la "ToList ()" parte de la línea "Ejecutar ()", pero cuando intento para ver el conjunto de resultados en el depurador, se muestra una excepción que lee, "Sólo una sola enumeración es apoyado por este IEnumerable. "

Por lo que yo puedo decir, mi código de cliente es el primer sospechoso. Después de todo, todos los otros programas de prueba que mi operación de servicio de datos está produciendo los resultados deseados.

¿Necesito hacer algo diferente para obtener la lista IEnumerable de objetos del servicio de datos?

Entiendo que hay una opción CreateQuery (), pero he leído que Ejecutar () es la ruta más apropiada para este escenario.

¿Fue útil?

Solución

Es probablemente debido a esto:

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

Asumo que la propiedad Id de la entidad GPS es la clave principal. En su ejemplo se está ajustando el ID de cada Gps devueltos a cero. En la biblioteca de cliente de WCF Data Services, las entidades con la misma clave primaria son tratados como la misma instancia tanto para el seguimiento de cambios razones y para que gráficos de objetos se comportan como era de esperar en un entorno orientado a objetos, la referencia de desviarse tales como .NET.

Si por alguna razón no se puede dar a las entidades Gps un identificador único, considerar el uso de un GUID para la clave principal.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top