2016-07-23 1 views
0

Я играю с демо Trippin OData из https://github.com/OData/ODataSamples/tree/master/Scenarios/TripPin/src/webapi используя код # клиента OData C сгенерированный шаблоном OData вносимого следующего расширение VS: enter image description hereКак запросить объекты, имеющие более одного вложенного объекта, с использованием сгенерированного кода клиента C# OData?

C# код просты:

var dc = new DefaultContainer(new Uri("http://canws212:23890/")); 
dc.People.AddQueryOption("$expand", "Trips").Where(p => p.Trips.Any()).First(); 

Это возвращает первый объект Person, имеющий любые дочерние объекты Trip в Trips.

Но теперь я хочу, чтобы получить первый Person объект, имеющий более одного Trip ребенка:

dc.People.AddQueryOption("$expand", "Trips").Where(p => p.Trips.Count() > 1).First(); 

Это не работает. Запрос/ответ, как захваченный стельку являются:

Запрос

GET http://canws212:23890/People?$filter=Trips/$count%20gt%201&$top=1&$expand=Trips HTTP/1.1 
OData-Version: 4.0 
OData-MaxVersion: 4.0 
Accept: application/json;odata.metadata=minimal 
Accept-Charset: UTF-8 
User-Agent: Microsoft ADO.NET Data Services 
Host: canws212:23890 
Connection: Keep-Alive 

Response

HTTP/1.1 400 Bad Request 
Cache-Control: no-cache 
Pragma: no-cache 
Content-Type: application/json; odata.metadata=minimal; charset=utf-8 
Expires: -1 
Server: Microsoft-IIS/8.0 
OData-Version: 4.0 
X-AspNet-Version: 4.0.30319 
X-SourceFiles: =?UTF-8?B?RDpcRGF5Zm9yY2VcU291cmNlXFJlcG9zXE9EYXRhU2FtcGxlc1xTY2VuYXJpb3NcVHJpcFBpblxzcmNcd2ViYXBpXE9EYXRhU2FtcGxlcy5XZWJBcGlTZXJ2aWNlXFBlb3BsZQ==?= 
X-Powered-By: ASP.NET 
Date: Sat, 23 Jul 2016 01:23:41 GMT 
Content-Length: 1604 

{ 
    "error":{ 
    "code":"","message":"The query specified in the URI is not valid. The method or operation is not implemented.","innererror":{ 
     "message":"The method or operation is not implemented.","type":"System.NotImplementedException","stacktrace":" at Microsoft.OData.Core.UriParser.Visitors.QueryNodeVisitor`1.Visit(CountNode nodeIn)\r\n at Microsoft.OData.Core.UriParser.Semantic.CountNode.Accept[T](QueryNodeVisitor`1 visitor)\r\n at System.Web.OData.Query.ParameterAliasNodeTranslator.Visit(BinaryOperatorNode nodeIn)\r\n at Microsoft.OData.Core.UriParser.Semantic.BinaryOperatorNode.Accept[T](QueryNodeVisitor`1 visitor)\r\n at System.Web.OData.Query.FilterQueryOption.get_FilterClause()\r\n at System.Web.OData.Query.Validators.FilterQueryValidator.Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings)\r\n at System.Web.OData.Query.FilterQueryOption.Validate(ODataValidationSettings validationSettings)\r\n at System.Web.OData.Query.Validators.ODataQueryValidator.Validate(ODataQueryOptions options, ODataValidationSettings validationSettings)\r\n at System.Web.OData.Query.ODataQueryOptions.Validate(ODataValidationSettings validationSettings)\r\n at System.Web.OData.EnableQueryAttribute.ValidateQuery(HttpRequestMessage request, ODataQueryOptions queryOptions)\r\n at System.Web.OData.EnableQueryAttribute.ExecuteQuery(Object response, HttpRequestMessage request, HttpActionDescriptor actionDescriptor)\r\n at System.Web.OData.EnableQueryAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)" 
    } 
    } 
} 

Что не так? Является ли это дефектом образца приложения TripPin или я делаю что-то неправильно? Как это исправить?

EDIT

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

ответ

0

При запуске C# код

dc.People.AddQueryOption("$expand", "Trips").Where(p => p.Trips.Count() > 1).First(); 

Odata.Client API преобразовать запрос к URL.

Сгенерированный URL в вашем случае:

http://canws212:23890/People?$filter=Trips/$count gt 1&$top=1&$expand=Trips 

который не соответствует URL конвенции OData V4

$ фильтр применяется только на свойства класса (людей), и класс Люди не могут перейти к классу Trip, используя ключевое слово $ filter, и нет счетчика свойств.

Вы расширяете Путешествие по ключевому слову Expand

читать больше о OData версии 4.0.URL Условные обозначения:

http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part2-url-conventions.html

так, вы получите сообщение об ошибке

edit2:

Чтобы получить первый Person объект, имеющий более чем один поездки

(я проверить его с адресом: http://services.odata.org/V4/TripPinServiceRW)

var dc = new DefaultContainer(new Uri("http://canws212:23890")); 
var firstPerson = dc.People.AddQueryOption("$expand", "Trips") 
          .ToList() 
          .FirstOrDefault(p => p.Trips.Count > 1); 
Console.WriteLine("{0} have: {1} trip", firstPerson.FirstName, firstPerson.Trips.Count); 
//The result: Russell have: 3 trip 

Edit: 3 , если рассмотреть пример 28, в URL:

http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part2-url-conventions.html

Example 28: entity count in a $filter expression. 
http://host/service/Categories?$filter=Products/$count gt 0 

вы найдете, что поддержка V4 COUNT свойству так, МОЕГО Заключения

Демо-сайт TripPin не соответствует URL Конвенции V4

и ваш запрос является допустимым, но не может быть выполнен (без всякой поддержки счета)

http://canws212:23890/People?$filter=Trips/$count gt 1&$top=1&$expand=Trips 
+0

если мой ответ удовлетворит вас, пометить его как решить –

+0

решения вы предлагаете не работают. Вы протестировали его? – mark

+0

Я изменил код, он работает, вы можете пересмотреть :) –