Listar registros com ASP.NET MVC.

Fala pessoal, resolvi escrever um pouco sobre uma rotina muito comum em uma aplicação web, consultar dados no banco e mostrar em tela.

Vou fazer uma série de artigos demonstrando várias maneiras de fazer esse tipo de funcionalidade com ASP.NET MVC, para isso criei um sistema bem simples que lista tarefas cadastradas, um “TODO LIST”.

O primeiro modo de visualizar os dados é um componente do próprio .NET, o WebGrid, este componente faz parte da biblioteca System.Web.Helpers e cumpre bem o papel de visualizar os dados, possui paginação e ordenação e é bem simples de implementar.

Abaixo o resultado da minha consulta utilizando o WebGrid:
artigo_lista1

Para isso criei uma classe no meu domínio chamada de Todo com a seguinte estrutura:

namespace TutorialGrid.Domain
{
	public class Todo
	{
		public int Id { get; set; }
		public string Title { get; set; }
		public DateTime DataOpen { get; set; }
		public DateTime? DataClosed { get; set; }
		public string Description { get; set; }
		public bool Closed { get; set; }
	}
}

Na minha DLL de acesso ao banco de dados, utilizo o Entity Framework Code First, o intuito deste post é falar sobre grids portanto se houver dúvidas quanto a implementação das classes, comenta que respondo de prontidão.

Interface:

namespace TutorialGrid.Domain.Repositories
{
	public interface ITodoRepository: IDisposable
	{
		List<Todo> Get();
		List<Todo> GetPaginate(int skip = 0, int take = 25);	
		Todo Get(int id);
		void Create(Todo todo);
		void Update(Todo todo);
		void Delete(int id);
	}
}

Implementação do método GET:

namespace TutorialGrid.Data.Repositories
{
	public class TodoRepository : ITodoRepository
	{
		private AppDataContext _db;

		public TodoRepository()
		{
			_db = new AppDataContext();
		}

		public List<Todo> Get()
		{
			return _db.Todos.ToList();
		}
        }
}

Na camada web criei um view model chamado TodoViewModel com a seguinte estrutura:

namespace TutorialGrid.Web.ViewModels
{
	public class TodoViewModel
	{
		public int Id { get; set; }

		[Required(ErrorMessage = "O campo titulo é obrigatório")]
		[Display(Name = "Titulo")]
		public string Title { get; set; }
		[Display(Name = "Tarefa criado em:")]
		public DateTime DataOpen { get; set; }
		
		[Display(Name = "Tarefa realizada em:")]
		public DateTime? DataClosed { get; set; }

		[Required(ErrorMessage = "O campo descrição é obrigatório")]
		[Display(Name = "Descrição")]
		public string Description { get; set; }
		
		[Display(Name = "Tarefa Finalizada")]
		public bool Closed { get; set; }
	}
}

Código do controller:

public class TodoController : Controller
{
    private ITodoRepository _repository = new TodoRepository();
    public ActionResult IndexWithWebGrid()
    {
       var listVM = 
          ConvertListModelToListViewModel(_repository.Get());
       return View(listVM);
    }
}

O método ConvertListModelToListViewModel eu fiz simplesmente para transferir a lista de model para uma lista de view model, poderia aqui usar o Automapper de boa que iria funcionar. Depois faço um exemplo com AutoMapper para mostrar!.

Código do método ConvertListModelToListViewModel:

private List<TodoViewModel> ConvertListModelToListViewModel(List<Todo> listModel)
{
	List<TodoViewModel> listViewModel = new List<TodoViewModel>();
	foreach (Todo todo in listModel)
	{
		TodoViewModel viewModel = new TodoViewModel();
		viewModel.Id = todo.Id;
		viewModel.Title = todo.Title;
		viewModel.Description = todo.Description;
		viewModel.DataOpen = todo.DataOpen;
		viewModel.DataClosed = todo.DataClosed;
		viewModel.Closed = todo.Closed;
		listViewModel.Add(viewModel);
	}
	return listViewModel;
}

Enfim o código da View:

@model IEnumerable<TutorialGrid.Web.ViewModels.TodoViewModel>
@{
    ViewBag.Title = "IndexWithWebGrid";
    Layout = "~/Views/Shared/_Layout.cshtml";
    var grid = new WebGrid(source: Model, canPage: true, rowsPerPage: 10);
    grid.Pager(WebGridPagerModes.All);
}
<style type="text/css">
   .webgrid-row-style {	padding: 3px 7px 2px;}
</style>
<h2>Listando tarefas com o WebGrid</h2>
<div id="webgrid">
	@grid.GetHtml(
	  tableStyle: "table table-responsive table-striped table-bordered table-hover ",
	  headerStyle: "wedgrid-header",
	  footerStyle: "",
	  rowStyle: "webgrid-row-style",
	  columns: grid.Columns(
		grid.Column(columnName: "Id", header: "Id"),
		grid.Column(columnName: "Title", header: "Titulo"),
		grid.Column(columnName: "DataOpen", header: "Criado em:"),
		grid.Column(columnName: "Description", header: "Descrição"),
		grid.Column(header:"Fechado?", format:@<text><input type="checkbox" checked="@item.Closed" disabled="disabled" /></text>),
		grid.Column(columnName: "DataClosed", header: "Realizado em:")
	  )
	)
</div>

artigo_lista2

O caso acima não é o melhor cenário, tendo em vista que a paginação ocorre do lado client, ou seja efetuamos a busca de todos os registros no banco e deixamos a cargo do client a paginação.

Este cenário é ideal para mostrar dados de tabelas que temos a certeza que não possuem muitos dados. Para tabelas com muitos registros devemos sempre implementar a paginação do lado server, nos próximos artigos desta série vou mostrar uma forma de fazer essa funcionalidade.

É isso ae pessoal, no próximo artigo da série sobre grids vou demonstrar o uso do Datatables com a mesma estrutura de dados acima.

Valeu e se ajudou posta um comentário, os comentários ajudam a melhorar, tanto os positivos quanto os negativos, então todos são bem vindos!!

C# – Como contar itens duplicados em listas genéricas.

É muito comum você precisar encontrar os itens distintos de uma lista genérica e é uma coisa muito fácil de fazer usando o Linq, precisei fazer algo parecido um dia desses em um projeto, vou deixar como dica, nunca se sabe quando iremos precisar.

No meu caso precisava saber se existiam objetos com propriedades iguais na minha coleção para efetuar uma validação, é mais ou menos o cenário abaixo.

Primeiro vamos criar uma classe chamada Pessoa bem simples:

public class Pessoa
{
        public Pessoa(int id, string nome, string sobrenome)
	{
		this.Id = id;
		this.Nome = nome;
		this.SobreNome = sobrenome;
	}
	public int Id { get; set; }
	public string Nome { get; set; }
	public string SobreNome { get; set; }
}

Depois vamos criar uma lista com algumas “Pessoas” e listar em tela três valores:

  • a quantidade de itens duplicados com mesmo id, nome e sobrenome;
  • a quantidade de itens duplicados com mesmo nome e sobrenome;
  • a quantidade de itens duplicados somente com o mesmo sobrenome.
  • class Program
    {
    static void Main(string[] args)
    {
    	List<Pessoa> pessoas = new List<Pessoa>();
    	pessoas.Add(new Pessoa(1,"Jose","Silva"));
    	pessoas.Add(new Pessoa(2,"Maria","Gomes"));
    	pessoas.Add(new Pessoa(1,"Jose","Silva"));
    	pessoas.Add(new Pessoa(3,"Roberto","Justus"));
    	pessoas.Add(new Pessoa(4,"Alice","Silva"));
    	pessoas.Add(new Pessoa(1,"Jose","Silva"));
    
    	int itens_duplicados = pessoas
    		.GroupBy(p => new { p.Id, p.Nome, p.SobreNome })
    		.Where(x => x.Count() > 1)
    		.Sum(x => x.Count());
    
    	int itens_duplicados_por_nome_e_sobrenome = pessoas
    		.GroupBy(p => new { p.Nome, p.SobreNome })
    		.Where(x => x.Count() > 1)
    		.Sum(x => x.Count());
    			
    	int itens_duplicados_por_sobrenome = pessoas
    		.GroupBy(p => new { p.SobreNome })
    		.Where(x => x.Count() > 1)
    		.Sum(x => x.Count());
    
    	Console.WriteLine("Itens duplicados: " + itens_duplicados);
    	Console.WriteLine("Itens com mesmo nome e sobrenome: " + itens_duplicados_por_nome_e_sobrenome);
    	Console.WriteLine("Itens com mesmo sobrenome: " + itens_duplicados_por_sobrenome);
    	Console.ReadLine();
    }
    }
    

    itensDuplicados

    É isso ae se gostou ou ajudou comenta para incentivar!!
    Um abraço.