I metodi di estensione C# sono disponibili su IQueryable
, ad es. FindNewCustomers()
e FindCustomersRegisteredAfter(int year)
e così via che uso per "concatenare" una query per LINQ a SQL.Problema di query compilato da LINQ a SQL (funziona come query non compilata)
Ora al mio problema: Voglio creare query compilate, per es .:
private static Func<MyDataContext, SearchInfo, IQueryable<Customer>>
CQFindAll =
CompiledQuery.Compile((MyDataContext dc, SearchInfo info) =>
dc.Contacts.Select(c => c).FindCustomersRegisteredAfter(info.RegYear)
.OrderBy(info.OrderInfo)
.Skip(info.SkipCount)
.Take(info.PageSize));
Il metodo FindCustomersRegisteredAfter(int year)
è un metodo di estensione prendere una IQueryable
e ritorno lo stesso. Il metodo OrderBy
è anche un metodo di estensione (System.Linq.Dynamic) che crea un'espressione dinamica basata su una stringa (ad esempio, "FirstName ASC" ordinerà il campo FirstName in ordine crescente). Skip
e Take
sono i metodi integrati.
Quanto sopra (non come query compilata, ma query regolare) funziona perfect. Una volta che l'ho messo in una query compilata, mi ha colpito il seguente errore:
Method 'System.Linq.IQueryable`1[Domain.Customer] FindCustomersRegisteredAfter[Customer](System.Linq.IQueryable`1[Domain.Customer], Int32)' has no supported translation to SQL.
Ancora una volta, Questo funziona perfettamente se la query non è compilato, solo una query LINQ regolare. L'errore appare solo una volta all'interno di CompiledQuery.Compile().
Aiuto ??!
Edit: Se creo la query tramite interrogazione var = (...) allo stesso modo all'interno di CompiledQuery.Compile, questa è la SQL generato:
SELECT [t1].[Id], [t1].[FirstName], [t1].[LastName],
[t1].[RegYear], [t1].[DeletedOn]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [t0].[LastName]) AS [ROW_NUMBER],
[t0].[Id], [t0].[FirstName], [t0].[LastName], [t0].[RegYear],
[t0].[DeletedOn]
FROM [dbo].[Contacts] AS [t0]
WHERE ([t0].[RegYear] > @p0) AND ([t0].[DeletedOn] IS NULL)
) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p1 + 1 AND @p1 + @p2
ORDER BY [t1].[ROW_NUMBER]
Così si vede che il SQL è tutto perfettamente traducibile, quindi devo solo riempire @ p0, @ p1 e @ p2 perché funzioni ripetutamente! Cosa c'è di sbagliato in CompiledQuery.Compile?!?
Aggiornamento: Comprendo che OrderBy non può funzionare (poiché non è un parametro @p). Sto ancora cercando di capire perché CompiledQuery.Compile non funzionerà con i miei metodi di estensione però. Le informazioni su Internet relative a questo argomento sono praticamente inesistenti.
Non capisco perché questo è wiki della comunità. – JustLoren