Les comparto mi funcion generica que aprovecha el uso de funciones anonimas como parametros para filtrar, ordenar y seleccionar los datos dandole dinamismo a la implementacion. considere _librosLt como el listado de libros disponibles para consultar
publicIEnumerable<dynamic>GetCustomBook(Func<Book, dynamic> select,Func<Book, bool> where,Func<Book, object> order, int take, int skip =0){returnthis._librosLt.Where(where).OrderBy(order).Take(take).Select(select);}
Y asi seria su invocacion
LinqQueries queries =newLinqQueries();var selectCustom = queries.GetCustomBook(select:x=>newBook{Title= x.Title,PageCount= x.PageCount},where:x=> x.PageCount>400,order:x=> x.PublishedDate,take:4,skip:0);foreach(var i in selectCustom)Console.WriteLine(string.Format("{0, -60} {1, 15}\n", i.Title, i.PageCount));
para que pides skip si no lo implementas
Operador Select
Nos permite seleccionar campos específicos de un objeto, para mejorar el rendimiento y ahorrar espacio en memoria.
me demoré como 2h pero pude con el reto ajajajaja
public List<Book> getTop3FromBooks(IEnumerable<Book> books){
return books.Take(3).Select(p=> new Book(){Title = p.Title, PageCount = p.PageCount}).ToList();
}
publicclassBookDTO{public string Title{get;set;}public int PageCount{get;set;}}publicList<BookDTO>getTop3FromBooksQuery(IEnumerable<Book> books){return(from b in books select newBookDTO{Title= b.Title,PageCount=b.PageCount}).Take(3).ToList();}
publicclassItem{public string Title{ get; set;}public int PageCount{ get; set;}}publicIEnumerable<Item>seleccionarTituloYNumPagDeLosPrimerosTresLibros(){return booksCollection.Take(3).Select(x=>newItem(){Title=x.Title,PageCount=x.PageCount});}
A continuación les comparto lo practicado en este clase, utilizando Extension method y query expression. También quise agregar un ejercicio con un mayor nivel de dificultad, tomándo en cuenta clases pasadas.
//Extension Method
return BooksCollections
.Take(3)
.Select(p => new Book { Title = p.Title, PageCount = p.PageCount });
//Query expression
var query = (from p in BooksCollections
select new Book { Title = p.Title, PageCount = p.PageCount })
.Take(3);
return query;
//Mi reto
var query = (from p in BooksCollections
where p.Title.Contains("Java")
select new Book { Title = p.Title, PublishedDate = p.PublishedDate})
.Take(2);
return query;
```Espero les ayude :D
public IEnumerable<Book>TresPrimerosLibros(){return librosCollection.Take(3).Select(p=> new Book(){ Title = p.Title, PCount = p.PageCount })}
todo quiero saber su significado
La selección dinámica es el arte de extraer solo lo que necesitas, justo cuando lo necesitas, en lugar de cargar con todo el peso de un conjunto de datos completo. Es la diferencia entre llevarte toda la biblioteca a casa o simplemente sacar el libro que vas a leer hoy.
Si tuvieras que elegir una sola pieza de información de un registro complejo para optimizar tu consulta, ¿cuál sería tu criterio para decidir qué es "esencial" y qué es "ruido"?
Saludos Miguel.
Gracias por el contenido de formación, es excelente .
Esta técnica de Linq nos facilita un poco parte del trabajo de obtener los objetos DTO a nivel de vista (ViewObject) a partir de de los objetos de Dominio, por ejemplo (los Entity) y evitar usar librerías de terceros como por ejemplo AutoMapper
Aprovecho la oportunidad para saber tu opción de un tema relacionado con DTO.
Siguiendo las recomendaciones de DDD y Arquitectura limpia, y tonando como base la clase Book de tu ejemplo, imaginemos que esta clase representa una entidad de negocio, entonces, el lugar ideal seria colocarla en la capa de Dominio o ```
namespace Xyx.Domain.Entityes
++LAPREGUNTAES:++**¿Dónde colocarías las clases DTO**BookRequesty****BookResponse**?OPCIONESDEREPSUESTA:En la **capa transversal** o común:
Ojala pueda contar con tu respuesta,así tendré otra perspectiva sobre este dilema y tomar la decisión correcta.El problema esta en que estas clases por su definición, forma y uso pueden ser candidatas a formar parte de cualquiera de esas tres capas, por su puesto, la capa de Servicio esta excluida como alternativa.Quedo atento.Muchas gracias por tu aportes.
Si la idea es crear un model para transferir datos entre las capas entonces deberia ir la capa de domain o dominio
publicIEnumerable<object>TituloNumeroPagdeTresPrimerosLibros(){var libros = librosCollection
.OrderByDescending(p=> p.PageCount).Take(3).Select(p=>new{Title= p.Title,Paginas= p.PageCount});foreach(var libro in libros){Console.WriteLine($"Título: {libro.Title}, Fecha de Publicación: {libro.Paginas}");}return libros ;}
public IEnumerable<Book> TresPrimerosLibros()
{
return (from l in librosColletion select new Book{ Title = l.Title , PageCount= l.PageCount}).Take(3) ;
}
Lo conseguí!:
Item.cs:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Curso_Linq{ internal classItem{public string?Title{ get; set;}public int PageCount{ get; set;}}}
LinqQueriesItems items =new();string formatoTextoItem ="{0, -60} {1, 15}";voidImprimirItems(IEnumerable<Item> listaDeItems){Console.WriteLine($"{formatoTextoItem}\n","Titulo","N. Paginas");foreach(var book in listaDeItems){Console.WriteLine($"{formatoTextoItem}", book.Title, book.PageCount);}}//* Primeros X libros filtadros con SelectImprimirItems(items.PrimerosXLibros(3));
Esta parece una excelente oportunidad para aplicar el patrón creacional Builder