0

我有一个从 ApiController 派生的 WebApi 控制器,它具有服务操作:

 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;
        }
    }

我还为 Airport 实体提供了 OData 服务。由于 .net webapi odata 还不支持 odata 功能(服务操作?),我需要创建一个辅助控制器(不是从 ODataController 派生的)。

我现在想要对 jaydata 做的是扩展上下文以在 odata 内容之外进行服务操作,一旦在 initService 中初始化了 db:

$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.
});

}

此控制器与 get 参数很好地配合使用,并在从 fiddler 手动调用时返回正确的 json。如何扩展 jaydata 上下文以具有 GetAirportsWithinRadius(airportId,radius) 方法?它的 url 需要手动设置,并且它的类型需要更改为 GET。此外,该方法是否可以与 odata 参数组合,因为它是用 [Queryable] 声明的。在 fiddler 中手动调用时,它的这一部分再次起作用。例如:

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

这很好地返回了两个机场实体对象......

谢谢

4

1 回答 1

1

谢谢@robesz - 在.net中创建参数化odata操作有一些微妙之处,这一直困扰着我(我之前尝试过操作,但无法让它工作),但这次我明白了:

 [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)});
    });

我高兴地跳上跳下:)

于 2013-06-27T16:53:36.453 回答