C'è qualcosa che può restituire IQueryable
per una query sql dinamica in Entity Framework 6?
Questo è quello che sto usando ora, ma sta tirando tutti i record (come previsto).
DbContext.Database.SqlQuery<T>("SELECT * FROM dbo.SomeDynamicView")
Il problema è che SqlQuery
restituisce DbRawSqlQuery
che è IEnumerable
.
dbo.SomeDynamicView
è una vista del database creata in fase di runtime.
No, non è possibile ottenere un IQueryable
da SqlQuery
* , questo perché ciò che IQueryable
sta facendo è costruire una stringa SQL in modo dinamico in base a quali filtri selezionare e dove inserire. Perché in SqlQuery
si fornisce la stringa che Entity Framework non può generare quella stringa dinamica.
Le opzioni sono in modo dinamico per costruire la stringa da te SqlQuery
in SqlQuery
e utilizzarla come oggetto IEnumerable
anziché come IQueryable
oppure utilizzare un DbSet
nel tuo DbContext
e fare il modo più "normale" di consentire al framework di entità di generare la query per te.
* Tecnicamente puoi chiamare AsQueryable () sul risultato, ma questo è solo un IEnumerable che finge di essere un IQueryable, non ti offre nessuno dei vantaggi dell'utilizzo di un IQueryable "Reale" come solo il recupero delle righe necessarie dal server .
So che questa domanda riguarda EF6 ma nel caso in cui qualcun altro si imbattesse in questa domanda ma fosse interessato a EFCore, questo è effettivamente possibile lì.
Esempio più semplice:
var user = new SqlParameter("user", "johndoe");
var blogs = context.Blogs
  .FromSqlRaw("EXECUTE dbo.GetMostPopularBlogsForUser @user", user)
.ToList();
parametri:
var user = new SqlParameter("user", "johndoe");
var blogs = context.Blogs
  .FromSqlRaw("EXECUTE dbo.GetMostPopularBlogs @filterByUser=@user", user)
.ToList();
Esempio più complesso (questo è più specificamente ciò che questa domanda chiede):
var searchTerm = ".NET";
var blogs = context.Blogs
.FromSqlInterpolated($"SELECT * FROM dbo.SearchBlogs({searchTerm})")
.Where(b => b.Rating > 3)
.OrderByDescending(b => b.Rating)
.ToList();
Query risultante per un esempio più complesso:
SELECT [b].[Id], [b].[Name], [b].[Rating]
FROM (
SELECT * FROM dbo.SearchBlogs(@p0)
) AS b
WHERE b."Rating" > 3
ORDER BY b."Rating" DESC
Alcune note su questo metodo:
SELECT *
per assicurarti che tutte le colonne vengano restituite dalla tabella. Include
funziona nelle normali query SQL (non necessariamente chiamate proc / function memorizzate).