ASP .NET Core 3.1 - CRUD básico usando DBFirst


Hoje vamos recordar como criar uma aplicação ASP .NET Core MVC e fazer o CRUD básico usando a abordagem DataBase First com ASP .NET .Core e EF Core 3.1.

A cada nova versão temos alterações e mudanças e por esse motivo aqui vai mais um artigo sobre como criar uma aplicação ASP .NET Core MVC usando o EF Core na versão 3.1. (Lembrando que até o fim do ano teremos o .NET 5)

Como o artigo é recorrente vou ser bem sucinto e objetivo.

A seguir temos o que é preciso para acompanhar o artigo. Todas as ferramentas listadas são GRÁTIS.

recursos:

Eu vou partir de um banco de dados já existente, um legado, e elegi o banco de dados Northwind.mdf como o banco que iremos usar.

Você pode pegar esse banco de dados neste link aqui :  Microsoft  - Banco de dados de Exemplo

Após baixar o script, execute-o no seu SQL Server Management Studio e crie o banco de dados Northwind.

Depois abra o VS 2019 Community e crie um novo projeto via menu File-> New Project;

Selecione o template ASP .NET Core Web Application, e, Informe o nome AspCRUD_Northwind;

A seguir selecione .NET Core e ASP .NET Core 3.1 e marque o template Web Application e as configurações conforme figura abaixo:

Depois que o projeto foi criado, precisamos adicionar a referência aos seguintes pacotes:

Esses pacotes são necessários para realizarmos o Scaffold das classes do Modelo e do Contexto(DbContext) a partir do banco de dados. (Para instalar use o comando Install-Package <nome> -version 3.1.3)

Gerando as classes do modelo de domínio e do contexto

O que vamos fazer agora é partir do banco de dados Northwind e gerar o modelo de entidades.

Para isso precisamos usar a ferramenta dotnet ef que tem que ser instalada usando o comando:

dotnet tool install --global dotnet-ef

Nota: Se obtiver um erro, desinstale a versão anterior e instale a versão atual

Agora com a ferramenta instalada, o comando que vamos usar tem a seguinte sintaxe:

dotnet ef dbcontext scaffold <string de conexão>  Provider -o Models -f -c DemoDbContext

Onde :

dotnet ef dbcontext scaffold - é o comando
<string de conexão> - é a string de conexão do banco de dados usado
Provider -  é o provedor do banco de dados
-o Models - é a pasta de sáida das classes geradas
-f - vai sobrescrevef um código anteriormente gerado
-c DemoDbContext - é o nome do DbContext usado na aplicação

Então para o banco de dados Northwind cuja string de conexão para o meu ambiente é :

Data Source=Macoratti;Initial Catalog=Northwind;Integrated Security=True

Temos o seguinte comando:

dotnet-ef dbcontext scaffold
"Data Source=Macoratti;Initial Catalog=Northwind;Integrated Security=True" Microsoft.EntityFrameworkCore.SqlServer
-o Models
-f -c NorthwinContext

Você deve executar este comando em uma única linha e em um prompt de comandos estando na pasta do projeto.

Após a execução abra a pasta Models e você verá um 'caminhão' de entidades geradas e também o arquivo NorthwinContext que representa o nosso arquivo de contexto.

Em seguida, precisamos instalar o pacote Microsoft.VisualStudio.Web.CodeGeneration.Design 3.1.2

Este pacote é necessário para gerar a classe do controlador e as views Razor do projeto.

Após você instalar o pacote vamos emitir o comando para gerar o controlador CategoriesController na pasta Controllers usando o seguinte comando:

dotnet aspnet-codegenerator controller -udl
-dc NorthwinContext -m Categories
-name CategoriesController
-outDir .\Controllers\

Este comando deve ser executado em uma única linha na pasta do projeto.

Abaixo temos a janela do prompt de comando com a execução:

Diferentemente do Scaffold das classes do modelo, não há como gerar controladores e views para todas as classes de modelo, precisamos executar o comando para cada classe de modelo individualmente.

Para gerar o controlador, os parâmetros datacontext (-dc) e model (-m) são necessários.

O parâmetro -udl especifica para usar o arquivo de Layout Padrão.

Podemos conferir na janela Solution Explorer a pasta Controllers e na pasta Views/Categories exibindo os arquivos criados:

Se você desejar pode executar o comando para todas as tabelas no banco de dados e gerar todos os controladores.

Após isso só falta definir no arquivo Startup, no método ConfigureServices, a configuração para o contexto da aplicação:

public void ConfigureServices(IServiceCollection services)
{
     services.AddDbContext<NorthwinContext>(
            options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

       services.AddControllersWithViews();
}

E no arquivo appsettings.json definir a string de conexão usada:

{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=Macoratti;Initial Catalog=Northwind;Integrated Security=True"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Ai, é só alegria...

Executando o projeto teremos o resultado abaixo:

Note que a exibição da imagem da categoria esta sendo feita como texto mas na classe do modelo de entidades gerada ela esta definida como um array de bytes.

Portanto, precisamos modificar um pouco o código e converter o array de bytes em uma imagem e devolvê-la. Podemos criar um método Action GetImageById que vai procurar os bytes da imagem usando o id e retornará um arquivo de imagem :

public IActionResult GetImageById(int id)
{
    var imageData = _context.Categories.Find(id).Picture;
    return File(imageData, "image/png");
}

E agora podemos usar assim na view Index.cshtml :

<img src="@Url.Action("GetImageById",new { id = item.CategoryId })" alt="@item.CategoryName" />

Isso seria suficiente para exibir as imagens, mas como as imagens estão armazenadas no banco de dados usando o formato do MS Access, temos que ajustar o código conforme abaixo:

  public IActionResult GetImageById(int id)
  {
            var offset = 78;
            var imageData = _context.Categories.Find(id).Picture;
            var bytes = new byte[imageData.Length - offset];
            Array.Copy(imageData, offset, bytes, 0, bytes.Length);
            return File(bytes, "image/png");
  }

Agora sim, vamos executar novamente e exibir as imagens:

E, assim vimos como partir do banco de dado,s gerar o modelo de entidades e a seguir gerar o controlador e as views usando os recursos do EF Core e da ASP .NET Core 3.1

Pegue o projeto completo aqui: AspCRUD_Northwind.zip  (sem as referências)

"Sede unânimes entre vós; não ambicioneis coisas altas, mas acomodai-vos às humildes; não sejais sábios em vós mesmos;"
Romanos 12:16

Referências:


José Carlos Macoratti