Saltar al contenido

Incluir con FromSqlRaw y procedimiento almacenado en EF Core 3.1

Esta es la solución más válida que te podemos brindar, pero primero estúdiala pausadamente y analiza si se puede adaptar a tu proyecto.

Solución:

En breve, no puede hacer eso (al menos para SqlServer). La explicación se encuentra en la documentación de EF Core – Consultas SQL sin procesar – Composición con LINQ:

Componer con LINQ requiere que su consulta de SQL sin formato sea componible, ya que EF Core tratará el SQL proporcionado como una subconsulta. Las consultas SQL que se pueden componer comienzan con el SELECT palabra clave. Además, el SQL pasado no debe contener ningún carácter u opción que no sea válida en una subconsulta, como:

  • Un punto y coma final
  • En SQL Server, una sugerencia de nivel de consulta final (por ejemplo, OPTION (HASH JOIN))
  • En SQL Server, un ORDER BY cláusula que no se usa con OFFSET 0 OR TOP 100 PERCENT en el SELECT cláusula

SQL Server no permite la composición sobre llamadas a procedimientos almacenados, por lo que cualquier intento de aplicar operadores de consulta adicionales a dicha llamada dará como resultado un SQL no válido. Usar AsEnumerable o AsAsyncEnumerable método justo después FromSqlRaw o FromSqlInterpolated métodos para asegurarse de que EF Core no intente componer sobre un procedimiento almacenado.

Además, desde Include / ThenInclude requiere EF Core IQueryable<>, AsEnumerable / AsAsyncEnumerable etc. no es una opción. Realmente necesita SQL componible, por lo tanto, los procedimientos almacenados no son una opción.

Sin embargo, en lugar de procedimientos almacenados, puede usar funciones con valores de tabla (TVF) o vistas de base de datos porque son componibles (select * from TVF(params) o select * from db_view) .

En mi caso, estaba convirtiendo EF de trabajo FromSql() con un código de procedimiento almacenado 2.1 a 3.1. Al igual que:

ctx.Ledger_Accounts.FromSql("AccountSums @from, @until, @administrationId",
                                                            new SqlParameter("from", from),
                                                            new SqlParameter("until", until),
                                                            new SqlParameter("administrationId", administrationId));

Dónde AccountSums es un SP.

Lo único que tenía que hacer era usar FromSqlRaw() y añadir IgnoreQueryFilters() para que vuelva a funcionar. Al igual que:

ctx.Ledger_Accounts.FromSqlRaw("AccountSums @from, @until, @administrationId",
               new SqlParameter("from", from),
               new SqlParameter("until", until),
               new SqlParameter("administrationId", administrationId)).IgnoreQueryFilters();

Esto se menciona en los comentarios, pero al principio me lo perdí, así que incluyo esto aquí.

Recuerda que tienes concesión de comentar tu experiencia si diste con la respuesta.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *