ContentType
--> EF model
ContentTypes
--> DTO
In my OData controller:
public Task<IQueryable<ContentTypes>> Get(ODataQueryOptions<ContentTypes> options)
{
var result = options.ApplyTo(_repository.Query().Get()
.Where(u => u.UserId == userId)
.OrderBy(o => o.Description))
.Cast<ContentTypes>();
return result;
}
I get an error 500 when trying to apply the ODataQueryOptions
. Since the class already inherits ODataController
do I even need to do theoptions.ApplyTo(...)
?
The solution for this was to ensure the return type is the the DTO's type, and that the ODataQueryOptions
are applied to the EF entity. I then use Automapper to map the result to the DTO.
I have updated the answer based on @Schandlich 's suggestions, however some issues persist:
[Queryable]
public virtual IHttpActionResult Get(ODataQueryOptions<ContentType> options)
{
var userId = 102; // mock
try
{
var results = options.ApplyTo(_uow.Repository<ContentType>()
.Query()
.Get()
.Include(u => u.User)
.Where(u => u.UserId == userId)
.OrderBy(o => o.Description)).Cast<ContentType>()
.Select(x => new ContentTypeDTO()
{
//projection goes here
ContentTypeId = x.ContentTypeId,
Description = x.Description,
UserDTO = new UserDTO
{
UserId = x.UserId,
UserName = x.User.UserName
}
});
return this.Ok(results);
}
catch (Exception ex)
{
throw ex;
}
}
The reason for using ODataQueryOptions
is that I want EF to handle the filtering down at the database call level. Otherwise, I would get all records returned, then the Queryable
would kick in to return, say the first page of results.
I removed the Automapper code, but curious as to why not use this?
As @Schandlich pointed out, however, this will not work for $select
or $expand
.