from example c# linq entities

example - select linq c# list



LINQ.Take() devuelve más elementos de los solicitados (1)

Tenemos una consulta simple de LINQ-to-Entities que debe devolver un número específico de elementos de una página en particular. El ejemplo de la solicitud puede ser:

var query = from r in records orderby r.createdDate descending select new MyObject() { ... }; //Parameters: pageId = 8, countPerPage = 10 List<MyObject> list = query.Skip(pageId * countPerPage).Take(countPerPage);

El ejemplo anterior funciona muy bien en la mayoría de los casos, pero a veces la lista tiene más de 10 elementos. Esto no parece ser siempre cierto y depende de los datos de la base de datos. Por ejemplo, cuando solicitamos la página 10 y pasamos countPerPage como 10, obtenemos 10 elementos. Pero cuando solicitamos la página 12 y pasamos countPerPage como 10, obtenemos 11 elementos. Luego, cuando pedimos la página 21, obtenemos 10 elementos una vez más.

¿Hay alguna razón posible por la que eso sucede?

ACTUALIZACIÓN: La consulta, por supuesto, no es tan simple, como lo es en el ejemplo, y contiene las consultas secundarias.

Y aquí hay un ejemplo más completo:

var elementsQuery = from m in entityContext.elements where m.elementSearchText.Contains(filter) orderby m.CreatedDate descending select new DataContracts.ElementForWeb() { FirstName = m.FirstName, LastName = m.LastName, Photos = (from p in m.Photos select p.ID), PlacesCount = m.Childs.Where(x => x.Place != null).Count() + ((m.MainChild != null)?1:0), SubElements = ( from t in m.Childs orderby t.CreatedDate descending select new DataContracts.ChildForWeb() { CommentsCount = t.ChildComments.Count, Photos = (from p in t.Photos select p.ID), Comments = (from c in t.ChildComments orderby c.CreatedDate descending select new DataContracts.CommentForWeb() { CommentId = c.ID, CommentText = c.CommentText, CreatedByPhotoId = c.Account.UserPhoto, CreatedDate = c.CreatedDate, }).Take(5) }).Take(5) }; List<DataContracts.ElementForWeb> elements = new List<DataContracts.ElementForWeb>( elementsQuery .Skip(pageId * countPerPage) .Take(countPerPage));

ACTUALIZACIÓN2 : Aquí hay una prueba aún más interesante.

for (var i = 0; i < 10; i++) { Service.GetElementsForWebPaged(12, 10, "", function (result) { console.log("Elements returned: " + result.length); }, function (error) { }); }

Los resultados son "impresionantes"!

Elements returned: 11 Elements returned: 11 Elements returned: 10 Elements returned: 11 Elements returned: 11 Elements returned: 10 Elements returned: 11 Elements returned: 10 Elements returned: 11 Elements returned: 11


Sería difícil probar esta respuesta porque depende de su esquema y datos de prueba, etc. Pero creo que puede estar teniendo problemas para mezclar los resultados de IQueryAble con los resultados de IEnumerable.

Recuerde, una consulta de linq-To-Entities no hace realmente un viaje de ida y vuelta a la base de datos hasta que se realiza un foreach o ToList ().

Yo sugeriría primero romper esto en pedazos:

var elementsQuery = from m in entityContext.elements where m.elementSearchText.Contains(filter) orderby m.CreatedDate descending; var elements = elementsQuery.Skip(pageId * countPerPage).Take(countPerPage)).ToList();

Entonces construye tu proyección ...

var elementsForWeb = from m in elements select new DataContracts.ElementForWeb() { ... }