Как потреблять операции службы данных WCF в клиентском приложении .NET?

StackOverflow https://stackoverflow.com/questions/4083547

Вопрос

Хорошо, люди, я новичок в службах данных и Linq в отчаянии необходимости некоторых руководств. Всего за несколько дней я столкнулся с многочисленными неожиданными препятствиями, и сейчас я застрял. Я надеюсь, что это просто типичные разочарования изучения нового инструмента.

У меня есть служба данных WCF для обслуживания данных из таблицы базы данных базы данных SQL Server из координат GPS. В частности, у меня есть метод эксплуатации сервиса, который позволяет указывать десятичную точность и диапазон широты / долготы, чтобы получить более общее представление данных.

В веб-браузере, кажется, работает так, как ожидалось. Однако, когда я пытаюсь вызвать операцию из моего клиента приложения, список, возвращаемый клиентом, отличается от списка, создаваемого сервисом.

Я буду использовать кусочки моего кода, чтобы объяснить детали:

Работа обслуживания данных:

    // 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-объектов, но они все одинаковое значение. Чтобы быть конкретным, дублированное значение является последним значением в моем ожидаемом наборе результатов. Я подтвердил это, вызвав эту операцию в веб-браузере и просматривая результаты.

Способ клиента:

// 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 ()» линию «Execute ()», но когда я пытаюсь просмотреть набор результатов в отладчике, он показывает исключение, которое читает, «только один перечисление поддерживается этому iEnumerable. "

Насколько я могу сказать, мой клиентский код сначала подозреваемый. В конце концов, каждый другой тест показывает, что операция моей службы данных производит желаемые результаты.

Нужно ли сделать что-то другое, чтобы получить IEnumerablebable List объектов из службы данных?

Я понимаю, что есть вариант CreateQuery (), но я прочитал, что Execute () является более подходящим путем для этого сценария.

Это было полезно?

Решение

Это, вероятно, из-за этого:

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

Я предполагаю, что свойство ID объекта GPS является вашим основным ключом. В вашем примере вы устанавливаете идентификатор каждого возвращенного GPS на ноль. В библиотеке клиентской библиотеки WCF Data Services, объекты с одинаковым первичным ключом рассматриваются как тот же экземпляр общих причин для отслеживания изменений, так и для того, чтобы графики объекта ведут себя, поскольку вы ожидаете в объектно-ориентированной, ориентированной на оборудовании, такие как .NET.

Если по какой-то причине вы не можете дать объекты GPS уникальный идентификатор, рассмотрите возможность использования GUID для первичного ключа.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top