The case: Since I am using Automapper, I execute the query before OData will do it's filtering. To prevent using more includes than necessary, I want to Include it only when it's present in the $expand
parameter of OData.
So far I can only find how to filter inside an .Include()
, but not how to filter on using an .Include()
at all.
The problem: It doesn't include the Addresses.
The code:
var locations = context.Locations;
if (oDataQueryParameters["$expand"].Contains("Addresses"))
{
locations.Include(l => l.Addresses);
}
locations.Where(l => l.CustomerId == userModel.CustomerId)
.AsNoTracking()
.ToList();
CodePudding user response:
The solution: I forgot to asign it to locations again. Now my code is like this and it works:
var locations = context.Locations.AsQueryable();
if (oDataQueryParameters["$expand"].Contains("Addresses"))
{
locations = locations.Include(l => l.Addresses);
}
locations = locations.Where(l => l.CustomerId == userModel.CustomerId)
.AsNoTracking();
var locationModels = Mapper.Map<List<LocationModel>>(locations.ToList());
CodePudding user response:
The problem I was having was caused by a misconfiguration of the service and the $expand was disabled
builder.Services.AddControllers().AddOData(options => options.Select().Filter().OrderBy().Expand());
Adding .Expand()
will solve. Now the action:
[EnableQuery]
[HttpGet]
public ActionResult<IEnumerable<SupplierOrder>> GetAll()
{
var orders = _ctx.SupplierOrders.AsNoTracking();
return Ok(orders);
}
The request https://localhost:7021/api/Order will produce
SELECT o."Id", o."Code", o."Discriminator"
FROM "Orders" AS o
and https://localhost:7021/api/Order?$expand=OrderRows will make the join
SELECT o."Id", o."Code", o."Discriminator", o0."Id", o0."ArticleId", o0."OrderId", o0."Position", o0."Quantity"
FROM "Orders" AS o
LEFT JOIN "OrderRow" AS o0 ON o."Id" = o0."OrderId"
ORDER BY o."Id"
Using .net6 webapp and Npgsql.EntityFrameworkCore.PostgreSQL, Microsoft.AspNetCore.OData 8.0.10