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 conOFFSET 0 OR TOP 100 PERCENT
en elSELECT
cláusulaSQL 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
oAsAsyncEnumerable
método justo despuésFromSqlRaw
oFromSqlInterpolated
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.