Tengo métodos de extensión C# en IQueryable
, p. FindNewCustomers()
y FindCustomersRegisteredAfter(int year)
y así sucesivamente, que utilizo para "encadenar" una consulta en conjunto para LINQ to SQL.Problema de consulta compilada de LINQ-a-SQL (funciona como una consulta no compilada)
Ahora a mi problema: Quiero crear consultas compiladas, por ejemplo .:
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));
El método FindCustomersRegisteredAfter(int year)
es un método de extensión de tomar una IQueryable
y devolver la misma. El método OrderBy
también es un método de extensión (System.Linq.Dynamic) que crea una expresión dinámica basada en una cadena (por ejemplo, "FirstClass ASC" clasificará el campo FirstName ascendente). Skip
y Take
son los métodos integrados.
La consulta anterior (no tan compilada, pero consulta regular) funciona perfecta. Una vez que lo puse en una consulta compilada, me golpeó el siguiente error:
Method 'System.Linq.IQueryable`1[Domain.Customer] FindCustomersRegisteredAfter[Customer](System.Linq.IQueryable`1[Domain.Customer], Int32)' has no supported translation to SQL.
Una vez más, esto funciona perfectamente si la consulta no es compilado, sólo una consulta LINQ regular. El error aparece solo una vez dentro de CompiledQuery.Compile().
Ayuda ??
Editar: Si creo la consulta a través de var query = (...) del mismo modo que en el interior de CompiledQuery.Compile, este es el SQL generado:
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]
para que veas que la SQL es perfectamente traducible, así que solo necesito completar @ p0, @ p1 y @ p2 para que esto funcione repetidamente. ¿Qué pasa con CompiledQuery.Compile?!?
Actualización: Entiendo que OrderBy no puede funcionar (ya que no es un parámetro @p). Todavía estoy intentando averiguar por qué CompiledQuery.Compile no funcionará con mis métodos de extensión. La información en internet sobre este tema es prácticamente inexistente.
No entiendo por qué esto es wiki de la comunidad. – JustLoren