Home > Blockchain >  How do I only add Includes to the EF query when $expand conditions of OData are met
How do I only add Includes to the EF query when $expand conditions of OData are met

Time:06-30

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

  • Related