Solo curiosidad sobre cómo se supone que Omitir & Take funciona. Obtengo los resultados que quiero ver en el lado del cliente, pero cuando conecto AnjLab SQL Profiler y miro el SQL que se está ejecutando, parece como si estuviera buscando y devolviendo todo el conjunto de filas al cliente.Entity Framework/Linq to SQL: Omitir y tomar
¿Realmente está devolviendo todas las filas y luego ordenando y estrechando cosas con LINQ en el lado del cliente?
He intentado hacerlo con Entity Framework y con Linq to SQL; ambos parecen tener el mismo comportamiento.
Noseguro de que hace alguna diferencia, pero estoy usando C# en VWD 2010.
Cualquier idea?
public IEnumerable<Store> ListStores(Func<Store, string> sort, bool desc, int page, int pageSize, out int totalRecords)
{
var context = new TectonicEntities();
totalRecords = context.Stores.Count();
int skipRows = (page - 1) * pageSize;
if (desc)
return context.Stores.OrderByDescending(sort).Skip(skipRows).Take(pageSize).ToList();
return context.Stores.OrderBy(sort).Skip(skipRows).Take(pageSize).ToList();
}
SQL resultante (Nota: Estoy excluyendo la consulta Conde):
SELECT
[Extent1].[ID] AS [ID],
[Extent1].[Name] AS [Name],
[Extent1].[LegalName] AS [LegalName],
[Extent1].[YearEstablished] AS [YearEstablished],
[Extent1].[DiskPath] AS [DiskPath],
[Extent1].[URL] AS [URL],
[Extent1].[SecureURL] AS [SecureURL],
[Extent1].[UseSSL] AS [UseSSL]
FROM [dbo].[tec_Stores] AS [Extent1]
Después de una investigación más profunda, he encontrado que los siguientes trabajos como yo esperaría que:
public IEnumerable<Store> ListStores(Func<Store, string> sort, bool desc, int page, int pageSize, out int totalRecords)
{
var context = new TectonicEntities();
totalRecords = context.Stores.Count();
int skipRows = (page - 1) * pageSize;
var qry = from s in context.Stores orderby s.Name ascending select s;
return qry.Skip(skipRows).Take(pageSize);
}
SQL resultante:
SELECT TOP (3)
[Extent1].[ID] AS [ID],
[Extent1].[Name] AS [Name],
[Extent1].[LegalName] AS [LegalName],
[Extent1].[YearEstablished] AS [YearEstablished],
[Extent1].[DiskPath] AS [DiskPath],
[Extent1].[URL] AS [URL],
[Extent1].[SecureURL] AS [SecureURL],
[Extent1].[UseSSL] AS [UseSSL]
FROM (SELECT [Extent1].[ID] AS [ID], [Extent1].[Name] AS [Name], [Extent1].[LegalName] AS [LegalName], [Extent1].[YearEstablished] AS [YearEstablished], [Extent1].[DiskPath] AS [DiskPath], [Extent1].[URL] AS [URL], [Extent1].[SecureURL] AS [SecureURL], [Extent1].[UseSSL] AS [UseSSL], row_number() OVER (ORDER BY [Extent1].[Name] ASC) AS [row_number]
FROM [dbo].[tec_Stores] AS [Extent1]
) AS [Extent1]
WHERE [Extent1].[row_number] > 3
ORDER BY [Extent1].[Name] ASC
Me gusta mucho la forma en que funciona la primera opción; Pasando una expresión lambda para ordenar. ¿Hay alguna forma de lograr lo mismo en la sintaxis LINQ to SQL orderby? Intenté usar qry.OrderBy (sort) .Skip (skipRows) .Take (pageSize), pero eso terminó dándome los mismos resultados que mi primer bloque de código. Me lleva a creer que mis problemas están de alguna manera vinculados a OrderBy.
====================================
problema resuelto
tuvo que envolver la función lambda entrante en la expresión:
Expression<Func<Store,string>> sort
puede darnos el código para el tipo func? –
Claro, solo estoy pasando un lambda. Ejemplos: x => x.Name, x => x.LegalName, x => x.YearEstablished.ToString() – Sam
Empezando a pensar que debería pasar una cadena y luego usar una instrucción switch para establecer el parámetro orderby apropiado para el LINQ query :(El primer método era mucho más fresco e implicaba mucho menos código. No puedo entender por qué no funciona correctamente. Sin saber exactamente qué está sucediendo, parece que .OrderBy y .OrderByDescending están desencadenando una recuperación de la base de datos, luego aplicando el ordenamiento, luego omitiendo y tomando. Quizás sea eso ... tal vez OrderBy no sepa cómo convertir x => x.Name en el SQL apropiado para que obtenga el conjunto de resultados y luego aplique el orden y el filtrado. – Sam