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()
{
...
}