Службы данных WCF Expand работают неожиданно, когда заданы определенные размеры страниц сущностей - PullRequest
1 голос
/ 10 мая 2011

При подготовке нашей службы данных WCF к работе мы столкнулись с проблемой поведения оператора расширения при включенном разбиении на страницы.

Если страница отключена, расширение работает, как ожидается. Но когда я включаю разбиение на страницы на любом из расширенных наборов сущностей, независимо от размера страницы, развернутые сущности отображаются на странице размером 1.

[UPDATE]

В отсутствие каких-либо дополнительных комментариев здесь или на форумах MSDN я создал ошибку в Connect . Может быть, кто-то за стеной докопается до сути!

Например, предположим, у меня есть следующая простая модель: Example Model

Он работает в сгенерированной базе данных SQL с некоторыми примерами данных:

INSERT INTO [dbo].[Towns] (Name) VALUES ('Berlin');
INSERT INTO [dbo].[Towns] (Name) VALUES ('Rome');
INSERT INTO [dbo].[Towns] (Name) VALUES ('Paris');

INSERT INTO [dbo].[Gentlemen] (Id, Name) VALUES (1, 'Johnny');

INSERT INTO [dbo].[Ladies] (Name, Town_Name, Gentleman_Id) VALUES ('Frieda', 'Berlin', 1);
INSERT INTO [dbo].[Ladies] (Name, Town_Name, Gentleman_Id) VALUES ('Adelita', 'Berlin', 1);
INSERT INTO [dbo].[Ladies] (Name, Town_Name, Gentleman_Id) VALUES ('Milla', 'Berlin', 1);
INSERT INTO [dbo].[Ladies] (Name, Town_Name, Gentleman_Id) VALUES ('Georgine', 'Paris', 1);
INSERT INTO [dbo].[Ladies] (Name, Town_Name, Gentleman_Id) VALUES ('Nannette', 'Paris', 1);
INSERT INTO [dbo].[Ladies] (Name, Town_Name, Gentleman_Id) VALUES ('Verona', 'Rome', 1);
INSERT INTO [dbo].[Ladies] (Name, Town_Name, Gentleman_Id) VALUES ('Gavriella', 'Rome', 1);

Служба данных проста (обратите внимание, что здесь пейджинг отключен):

namespace TestWCFDataService
{
    public class TestWCFDataService : DataService<TestModel.TestModelContainer>
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("Ladies", EntitySetRights.AllRead);
            config.SetEntitySetAccessRule("Gentlemen", EntitySetRights.AllRead);
            config.SetEntitySetAccessRule("Towns", EntitySetRights.AllRead);

            //config.SetEntitySetPageSize("Ladies", 10);
            //config.SetEntitySetPageSize("Gentlemen", 10);
            //config.SetEntitySetPageSize("Towns", 10);

            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }
    }
}

Теперь мой пользователь хочет найти каждого Lady, чей Town является "Берлином", а также, кто их Gentleman.

Запрос:

http://localhost:62946/TestWCFDataService.svc/Towns('Berlin')?$expand=Ladies/Gentleman

Когда я запускаю этот запрос (JSON, потому что версия Atom гигантская), я получаю ожидаемый результат; город с тремя дамами, у всех из которых джонни джентльмен.

var result = {
        "d": {
            "__metadata": {
                "uri": "http://localhost:62946/TestWCFDataService.svc/Towns('Berlin')", "type": "TestModel.Town"
            }, "Name": "Berlin", "Ladies": [
    {
        "__metadata": {
            "uri": "http://localhost:62946/TestWCFDataService.svc/Ladies(1)", "type": "TestModel.Lady"
        }, "Id": 1, "Name": "Frieda", "Gentleman": {
            "__metadata": {
                "uri": "http://localhost:62946/TestWCFDataService.svc/Gentlemen(1)", "type": "TestModel.Gentleman"
            }, "Id": 1, "Name": "Johnny", "Ladies": {
                "__deferred": {
                    "uri": "http://localhost:62946/TestWCFDataService.svc/Gentlemen(1)/Ladies"
                }
            }
        }, "Town": {
            "__deferred": {
                "uri": "http://localhost:62946/TestWCFDataService.svc/Ladies(1)/Town"
            }
        }
    }, {
        "__metadata": {
            "uri": "http://localhost:62946/TestWCFDataService.svc/Ladies(2)", "type": "TestModel.Lady"
        }, "Id": 2, "Name": "Adelita", "Gentleman": {
            "__metadata": {
                "uri": "http://localhost:62946/TestWCFDataService.svc/Gentlemen(1)", "type": "TestModel.Gentleman"
            }, "Id": 1, "Name": "Johnny", "Ladies": {
                "__deferred": {
                    "uri": "http://localhost:62946/TestWCFDataService.svc/Gentlemen(1)/Ladies"
                }
            }
        }, "Town": {
            "__deferred": {
                "uri": "http://localhost:62946/TestWCFDataService.svc/Ladies(2)/Town"
            }
        }
    }, {
        "__metadata": {
            "uri": "http://localhost:62946/TestWCFDataService.svc/Ladies(3)", "type": "TestModel.Lady"
        }, "Id": 3, "Name": "Milla", "Gentleman": {
            "__metadata": {
                "uri": "http://localhost:62946/TestWCFDataService.svc/Gentlemen(1)", "type": "TestModel.Gentleman"
            }, "Id": 1, "Name": "Johnny", "Ladies": {
                "__deferred": {
                    "uri": "http://localhost:62946/TestWCFDataService.svc/Gentlemen(1)/Ladies"
                }
            }
        }, "Town": {
            "__deferred": {
                "uri": "http://localhost:62946/TestWCFDataService.svc/Ladies(3)/Town"
            }
        }
    }
    ]
        }
    }

В конечном счете их будет много Towns, поэтому я включаю пейджинг для Town.

...
            config.SetEntitySetPageSize("Towns", 10);
...

Запрос продолжает работать, как ожидалось. Но также будет много Ladies и Gentlemen, поэтому я хочу иметь возможность ограничить количество возвращаемых результатов:

...
            config.SetEntitySetPageSize("Ladies", 10);
            config.SetEntitySetPageSize("Gentlemen", 10);
...

Но когда я устанавливаю размер страницы в наборе сущностей Леди или в наборе сущностей Джентльменов (или обоих), результаты моего запроса неожиданно меняются:

var result = {
    "d": {
        "__metadata": {
            "uri": "http://localhost:62946/TestWCFDataService.svc/Towns('Berlin')", "type": "TestModel.Town"
        }, "Name": "Berlin", "Ladies": {
            "results": [
{
    "__metadata": {
        "uri": "http://localhost:62946/TestWCFDataService.svc/Ladies(1)", "type": "TestModel.Lady"
    }, "Id": 1, "Name": "Frieda", "Gentleman": {
        "__metadata": {
            "uri": "http://localhost:62946/TestWCFDataService.svc/Gentlemen(1)", "type": "TestModel.Gentleman"
        }, "Id": 1, "Name": "Johnny", "Ladies": {
            "__deferred": {
                "uri": "http://localhost:62946/TestWCFDataService.svc/Gentlemen(1)/Ladies"
            }
        }
    }, "Town": {
        "__deferred": {
            "uri": "http://localhost:62946/TestWCFDataService.svc/Ladies(1)/Town"
        }
    }
}
]
        }
    }
}

Расширение включает только один из объектов Леди (хотя по крайней мере ее Джентльмен включен). Неважно, насколько велик размер страницы, запрос все равно возвращает только один объект в расширенной коллекции.

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

Для меня это поведение пахнет глючно, как в спецификации OData :

«URI с параметром системного запроса $ expand указывает, что записи, связанные с записью или коллекцией записей, определенных в разделе« Путь к ресурсам »URI, должны быть представлены встроенными (т.е. загруженными с нетерпением).»

Я неправильно понял спецификацию? Должен ли я ожидать такого поведения? Я просто хочу иметь возможность ограничивать размер страницы наборов сущностей при прямом доступе, но также иметь возможность загружать их с нетерпением.

Это ошибка в службах данных WCF? (или мой код? или мой мозг?)

[EDIT]

Дополнительная информация: в документации для Служб данных WCF указано, что:

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

Но я не могу найти объяснение того, почему размер страницы для связанных наборов сущностей по умолчанию равен 1, независимо от того, какой размер страницы указан.

[EDIT]

Еще больше информации: рассматриваемая версия - версия .NET 4 4.0.30319 с System.Data.Services версия 4.0.0.0. Это версия, поставляемая в комплекте с Visual Studio 2010 (с установленным пакетом обновления 1).

[EDIT]

Пример решения, показывающего поведение, теперь работает в github репозитории . Он включает подкачку в методе InitializeService и сценарии создания БД, который также добавляет некоторые примеры данных, чтобы мы были на одной странице.

Ответы [ 3 ]

1 голос
/ 31 марта 2012

Прошло несколько месяцев, но это очевидно будет исправлено в следующей версии:

Опубликовано Microsoft 15.12.2011 в 8:08

Спасибо за сообщение об этой проблеме. Мы подтвердили, что ошибка в Entity Framework вызывая эту проблему. Исправление потребовало внесения изменений в основные компоненты Entity Framework, которые поставляются в .NET Framework. Мы исправили ошибку, исправление будет включено в следующую версию .NET Framework.

0 голосов
/ 10 мая 2011

Ваш запрос: localhost: 62946 / TestWCFDataService.svc / Towns ('Berlin')? $ Expand = Ladies / Gentleman

не расширяет Ladies, только Gentelman.

запрос должен выглядеть следующим образом:

localhost: 62946 / TestWCFDataService.svc / Towns ('Berlin')? $ expand = Ladies, Ladies / Gentleman.

Надеюсь, это поможет!

Моника Фринту

0 голосов
/ 10 мая 2011

Какую версию WCF Data Services вы используете?Я обнаружил ошибку, связанную с использованием Expand с управляемой сервером подкачкой страниц в .NET Framework 4, но я подумал, что это касается только сущностей с составными ключами и при использовании опции OrderBy, которая, похоже, здесь не применима.Тем не менее, это определенно звучит как ошибка.

Вы пытались использовать Atom вместо JSON, и если да, то сущности в раскрытии все еще отсутствуют?

...