es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo puedes activar o desactivar las inclusiones en Hotchocolate para EFCore?

Entonces estoy tratando de descubrir cómo indicar a EfCore cuándo aplicar un include a un objeto IQueryable basado en si la solicitud GraphQl del cliente realmente incluye el objeto relacionado.

Ejemplo:

  • 2 Clases: Person, Payment
  • Estas se mantienen en 2 tablas diferentes y se relacionan Person -> Payment en una relación de uno a muchos
  • Tengo 1 consulta de GraphQl configurada para recuperar todas las personas en la base de datos:
  • [UseFiltering]
    [UseDbContext(typeof(DbAccess))]
    public IQueryable<Person> GetPeople([ScopedService] DbAccess db)
    {
        return db.People;
    }
    
  • Esto devuelve solo los campos de la tabla People
    por ejemplo:
    consulta:
    {people{sso,payments{amount, recipient{compayName}}}}
    respuesta:
    {
    “data”: {
    “people”: [
    {
    “sso”: “000-00-0003”,
    “payments”: null
    }
    ]
    }
    }
  • Para obtener los pagos, mi función GetPeople debe modificarse a lo siguiente:
  • [UseFiltering]
    [UseDbContext(typeof(DbAccess))]
    public IQueryable<Person> GetPeople([ScopedService] DbAccess db)
    {
        return db.People.Include(p => p.Payments);
    }
    
  • Esto funciona, pero genera una carga innecesaria cuando los pagos no forman parte de la solicitud (ya que el Include se ejecutará siempre).

Lo que me gustaría hacer sería algo como:

var baseQuery = db.People;
if (graphqlRequestIncludePayments)
{
    baseQuery.Include(p => p.Payments);
}
return baseQuery;

Pero no puedo averiguar cómo verificar la consulta de GraphQl para ver si se solicitan los pagos. Sé que GraphQl eliminará los datos excesivos antes de devolverlos al consumidor, pero eso puede ser mucho ancho de banda y memoria desperdiciados en el lado del servidor.

Siento que hay una forma de hacer esto en la función ObjectType.Configure de Hotchocolate, pero no puedo ver cómo.

Toda ayuda sería muy apreciada, gracias 🙂

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Una posible solución a este problema es utilizar el contexto de ejecución del esquema proporcionado por HotChocolate para verificar si el objeto relacionado (en este caso, Pagos) está siendo solicitado por el cliente.

    Dentro del método ObjectType.Configure, puedes acceder al contexto de ejecución del esquema a través del parámetro context. Este objeto contiene información sobre la ejecución actual de GraphQL, incluido el conjunto de selección del campo actual que se está solicitando.

    Aquí tienes un ejemplo de cómo podrías modificar el método GetPeople para incluir condicionalmente los Pagos según la solicitud del cliente:

    [UseFiltering]
    [UseDbContext(typeof(DbAccess))]
    public IQueryable<person> GetPeople([ScopedService] DbAccess db, [GraphQLContext] IResolverContext context)
    {
        var includePayments = context.FieldSelection.SelectionSet.Contains("payments");
        var baseQuery = db.People;
    
        if (includePayments)
        {
            baseQuery = baseQuery.Include(p => p.Payments);
        }
    
        return baseQuery;
    }
    

    En este ejemplo, estamos utilizando la propiedad FieldSelection del contexto del resolvedor para verificar si el campo “payments” está siendo solicitado por el cliente. Si es así, incluimos los Pagos relacionados en la consulta. De lo contrario, devolvemos la consulta base de Personas sin incluir los Pagos relacionados.

    Este enfoque debería permitirte optimizar tus consultas incluyendo solo los objetos relacionados cuando realmente se necesiten, sin consultar innecesariamente la base de datos.

Comments are closed.