i want list of distinct values odata endpoint. distinct or group isn't supported yet.
my uri query looks this
get /odata/products?$select=foo & $top=10 & $count=true & distinct=true
my controller
[enablequery] public iqueryable<foobarbaz> get(odataqueryoptions<foobarbaz> queryoptions, bool distinct) { //i've tried following return repository.asqueryable().distinct(); // , return repository.asqueryable().groupby(x => x.foo); // , iqueryable query = queryoptions.applyto(repository.asqueryable()); return query.distinct(); // can't call .distinct() here }
none work :(
the best solution solve problem defining collection action on resource.
first step : configure 'distinct' action in webapiconfig.cs
odataconventionmodelbuilder builder = new odataconventionmodelbuilder(); builder.entityset<foobarbaz>("foobarbazs");//resource name actionconfiguration distinct = builder.entity<foobarbaz>().collection.action("distinct");//name of action method distinct.returnscollectionfromentityset<foobarbaz>("foobarbazs");//return type of action distinct.parameter<string>("on");//property on collection filtered distinct config.routes.mapodataroute("odata", "odata", builder.getedmmodel());
second step : add action in foobarbazscontroller.cs returns collection of distinct entities
[enablequery]//enable $select,$expend queries [httppost]//all action methods of post type in web api public iqueryable<foobarbaz> distinct(odataactionparameters parameters) { string on = ""; if (!modelstate.isvalid) { throw new httpresponseexception(httpstatuscode.badrequest); } try { on = parameters["on"] string; } catch (nullreferenceexception ex) { httpresponsemessage message = new httpresponsemessage(httpstatuscode.badrequest); message.content = new stringcontent("{\"error\":\"invalid query -> on property not defined\"}"); throw new httpresponseexception(message); } catch (exception ex) { throw new httpresponseexception(httpstatuscode.badrequest); } propertyinfo[] props = new foobarbaz().gettype().getproperties(bindingflags.public | bindingflags.instance); var ispropertyexist = false; (int = 0; < props.length; i++) { if (props[i].name.equals(on)) { ispropertyexist = true; break; } } if (ispropertyexist) { var foobarbazcollection = db.foobarbazs.groupby(getgroupkey(on)).select(g => g.firstordefault());//select distinct entity on basis of property return foobarbazcollection ; } else { httpresponsemessage message = new httpresponsemessage(httpstatuscode.badrequest); message.content = new stringcontent("{\"error\":\"property '"+on+"' not exist}"); throw new httpresponseexception(message); } }
third step : add static method returns expression groupby on basis of property name.
private static expression<func<foobarbaz, string>> getgroupkey(string property) { var parameter = expression.parameter(typeof(foobarbaz)); var body = expression.property(parameter, property); return expression.lambda<func<foobarbaz, string>>(body, parameter); }
now build project , can query resource this
post /odata/foobarbazs/distinct http/1.1 host: localhost:9360 content-type: application/json cache-control: no-cache postman-token: 6d174086-7b97-76a2-679c-4dab3dfb5938 {"on":"propertyname"}
and can use $select , $expend this
post /odata/foobarbazs/distinct?$select=propertyname1,propertyname2 http/1.1 host: localhost:9360 content-type: application/json cache-control: no-cache postman-token: 6d174086-7b97-76a2-679c-4dab3dfb5938 {"on":"propertyname"}
i hope solve problem. +1 if do.
Comments
Post a Comment