Добавление определяемых вручную операций службы внутри initService для службы odata

У меня есть контроллер WebApi, производный от ApiController, который имеет сервисную операцию:

 public class Airports2Controller : ApiController
    {
        protected airportEntities db = new airportEntities ();

         [Queryable]
        [HttpGet]
        public IQueryable<Airport> GetAirportsWithinRadius(int airportId, int radius)
        {
            //var radius = (int)parameters["radius"];
            //var airportId = (int)parameters["airportId"];

            var resultAirports = GetAirportsWithinRadius2(airportId, radius);

            return resultAirports;            
        }


        private IQueryable<Airport> GetAirportsWithinRadius2(int airportId, int radius)
        {
            var airports = db.Airports.SqlQuery("select * from Airport a where (select GeoLocation from airport where Id = @p0).STDistance(a.GeoLocation)/1.852/1000.00 < @p1", airportId, radius);

            var airportIds = airports.Select(a => a.Id);
            var resultAirports = db.Airports.Where(a => airportIds.Contains(a.Id));

            return resultAirports;
        }
    }

У меня также есть служба odata для объекта Airport. Поскольку .net webapi odata еще не поддерживает функции odata (служебные операции?), мне нужно было создать вторичный контроллер (который не является производным от ODataController).

Что я хочу сделать сейчас с jaydata, так это расширить контекст, чтобы иметь операцию службы в дополнение к материалу odata после инициализации db в initService:

$data.initService("http://localhost:2663/odata");
            service.then(function (db) {
        //now here manually extend the definition of the context to include the GetAirportsWithinRadius service operation.
});

}

Этот контроллер хорошо работает с параметрами получения и возвращает правильный json при ручном вызове из скрипача. Как расширить контекст jaydata, чтобы иметь метод GetAirportsWithinRadius(airportId,radius)? Его URL-адрес нужно будет установить вручную, а его тип нужно будет изменить на GET. Кроме того, будет ли этот метод компоноваться с параметрами odata, поскольку он объявлен с [Queryable]. Опять же, эта часть работает при ручном вызове в скрипаче. Например:

http://localhost:2663/api/Airports2/GetAirportsWithinRadius?airportId=2112&radius=50&?$inlinecount=allpages&$top=2

Это прекрасно возвращает два объекта объекта аэропорта...

Спасибо


person t316    schedule 26.06.2013    source источник
comment
Эй, можно ли опубликовать вашу логику как действие веб-api odata? Вы можете вызывать действия на уровне набора сущностей и на уровне сущностей -jaydata.org/блог/   -  person Robesz    schedule 27.06.2013


Ответы (1)


Спасибо @robesz - были некоторые тонкости в создании параметризованных действий odata в .net, и это то, что меня мучило (раньше я пробовал действия, просто не мог заставить их работать), но на этот раз я понял:

 [Queryable]
        [HttpPost]
        public IQueryable<Airport> GetAirportsWithinRadius([FromBody] ODataActionParameters parameters)
        {
            if (!ModelState.IsValid)
            {
                throw new HttpResponseException(HttpStatusCode.BadRequest);
            }
            var radius = (int)parameters["radius"];
            var airportId = (int)parameters["airportId"];

            var resultAirports = GetAirportsWithinRadius2(airportId, radius);

            return resultAirports;            
        }

 ActionConfiguration getAirportsWithinRadius = modelBuilder.Entity<Airport>().Collection.Action("GetAirportsWithinRadius");
            getAirportsWithinRadius.Parameter<int>("airportId");
            getAirportsWithinRadius.Parameter<int>("radius");
            getAirportsWithinRadius.ReturnsCollectionFromEntitySet<Airport>("Airports");

Имея это на месте, теперь я могу сделать следующее с jaydata:

var service = $data.initService("http://localhost:2663/odata");
        return service.then(function (db) {
           airports = db.Airports.GetAirportsWithinRadius(2112,50);
           airports.filter("it.Abbrev== a", {a: 'C44'}).forEach(function(a){console.log(a.Abbrev)});
    });

Я прыгаю от радости :)

person t316    schedule 27.06.2013
comment
Ух ты! Потрясающе, поздравляю! :) - person Robesz; 28.06.2013