Início » ASP.NET » Iniciando com ASP.NET 4.5 Web Forms – Parte 3 – Criando o DAL (Data Access Layer)

Iniciando com ASP.NET 4.5 Web Forms – Parte 3 – Criando o DAL (Data Access Layer)

Esse tutorial descreve como criar, acessar, e revisar dados de uma base de dados usando ASP.NET Web Forms e Entity Framework Code First. É continuação do tutorial anterior “Criando o Projeto” e é parte da série de tutoriais Wingtip Toy Store. Quando você completar esse tutorial, terá construído um grupo de classes de acesso a dados que estão na pasta Models do projeto.

1 O que aprenderá:

  • Como criar o modelo de dados.
  • Como inicializar e alimentar a base de dados.
  • Como atualizar e configurar a aplicação para suportar a base de dados.

Essas são as características introduzidas no tutorial:

  • Entity Framework Code First
  • LocalDB
  • Data Annotations

2 Criando o Modelo de Dados

Entity Framework é um framework ORM (Object-Relational Mapping). Permite que você trabalhe com dados relacionais como objetos, eliminando a maioria de código de acesso a dados que você usualmente precisa escrever. Usando Entity Framework, você pode emitir consultas usando LINQ, e então recuperar e manipular dados como objetos fortemente tipados. LINQ fornece padrões para consulta e atualização de dados. Usar Entity Framework permite que você foque em criar o resto de sua aplicação, ao invés de focar nos fundamentos de acesso a dados. Posteriormente nesse tutorial, será mostrado como usar dados para popular navegação e consulta de produtos.

Entity Framework suporta um paradigma de desenvolvimento chamado Code First. Code First permite que você defina seus modelos de dados usando classes. Uma classe é um construtor que permite que você crie seus próprios tipos customizados agrupando variáveis de outros tipos, métodos e eventos. Você pode mapear classes para uma base de dados existente ou usá-las para gerar uma base de dados. Nesse tutorial, você criará o modelo de dados escrevendo classes de modelos de dados. E então, permitirá que o Entity Framework crie a base de dados dessas novas classes.

Começaremos criando entity classes que definem modelos de dadps para a aplicação Web Forms. Depois criará uma context class que gerencia as entity classes e fornece acesso a dados à base de dados. Criará também uma classe inicializadora que será usada para popular a base de dados.

2.1 Entity Framework e Referências

Por padrão, Entity Framework está incluso quando você cria uma nova aplicação ASP.NET usando o template Web Forms. Entity Framework pode ser instalado, desinstalado, e atualizado com o NuGet.

O pacote NuGet inclui os seguintes assemblies no seu projeto:

  • EntityFramework.dll – código usado pelo Entity Framework.
  • EntityFramework.SqlServer.dll – provider do Microsoft SQL Server para Entity Framework.

2.2 Entity Classes

As classes que você cria para definir o schema dos dados são chamadas entity classes. Se você é novo no design de base de dados, pense nas entity classes como definições de tabelas de uma base de dados. Cada propriedade na classe especifica uma coluna na tabela da base de dados. Essas classes fornecem uma estrutura leve, interface objeto-relacional entre código orientado a objeto e a estrutura relacional da tabela da base de dados.

Nesse tutorial, você começará adicionando uma entity class simples representando os schemas para produtos e categorias. A classe produtos conterá definições para cada produto. O nome de cada membro da classe produtos será ProductID, ProductName, Description, ImagePath, UnitPrice, CategoryID, e Category. A classe categoria conterá definições para cada categoria que um produto pode pertencer, como Car, Boat, ou Plane. O nome de cada membro da classe categoria será CategoryID, CategoryName, Description, e Products. Cada produto pertencerá a uma das categorias. Essas entity classes serão adicionadas a pasta existente no projeto chamado Models.

  1. Na Solution Explorer, clique com o botão direito na pasta Models e então selecione Add -> New Item.
  2. Figura 1 - Parte 3

    A caixa de diálogo Add New Item é exibida.

  3. Em Visual C# do painel Installed do lado esquerdo, selecione Code.
  4. Figura 2 - Parte 3

  5. Selecione Class no painel do centro e nomeie essa classe como Product.cs.
  6. Clique em Add. O novo arquivo da classe é exibido no editor.
  7. Substitua o código padrão pelo seguinte:
  8. using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.ComponentModel.DataAnnotations;
    
    namespace WingtipToys.Models
    {
    public class Product
    {
            [ScaffoldColumn(false)]
            public int ProductID { get; set; }
    
            [Required, StringLength(100), Display(Name = "Name")]
            public string ProductName { get; set; }
    
            [Required, StringLength(10000), Display(Name = "Product Description"), DataType(DataType.MultilineText)]
    
            public string Description { get; set; }
    
            public string ImagePath { get; set; }
    
            [Display(Name = "Price")]
            public double? UnitPrice { get; set; }
    
            public int? CategoryID { get; set; }
    
            public virtual Category Category { get; set; }
        }
    }
    
    
  9. Crie outra class repetindo os passos 1 até 4, entretanto, nomeie a nova classe como Category.cs e substitua o código padrão pelo seguinte:
  10. 
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.ComponentModel.DataAnnotations;
    
    namespace WingtipToys.Models
    {
        public class Category
        {
            [ScaffoldColumn(false)]
            public int CategoryID { get; set; }
    
            [Required, StringLength(100), Display(Name = "Name")]
            public string CategoryName { get; set; }
    
            [Display(Name = "Product Description")]
            public string Description { get; set; }
    
            public virtual ICollection<Product> Products { get; set; }
        }
    }
    
    

Como mencionado anteriormente, a classe Category representa o tipo de produto que a aplicação é projetada para vender (como Carros, Boats, Rockets, dentre outros), e a classe Product representa os produtos individuais (brinquedos) na base de dados. Cada instância de um objeto Product corresponderá a uma linha dentro de uma tabela de base de dados relacional, e cada propriedade da classe Product mapeará uma coluna na tabela de base de dados relacional. Posteriormente nesse tutorial, será revisado os dados dos produtos contidos na base de dados.

2.3 Data Annotations

Você deve ter notado que certos membros das classes tem atributos especificando detalhes sobre o membro, como ScaffoldColumn(false). Isso são data annotations. Os atributos data annotation podem descrever como validar entrada de usuário para aquele membro, especificar formatação para ele, e especificar como é modelado quando a base de dados é criada.

3 Context Class

Para começar usar as classes para acesso a dados, você deve definir uma context class. Como mencionado anteriormente, a context class gerencia as entity classes (como a classe Product e Category) e fornece acesso a dados para a base de dados.

Esse procedimento adicionada uma nova context class em C# para a pasta Models.

  1. Clique com o botão direito na pasta Models e então selecione Add -> New Item.
  2. Selecione Class do painel central, e nomeie como ProductContext.cs e clique em Add.
  3. Substitua o código padrão contido na classe pelo seguinte:
  4. using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Data.Entity;
    
    namespace WingtipToys.Models
    {
        public class ProductContext : DbContext
        {
            public ProductContext()
                : base("WingtipToys")
            { }
    
            public DbSet<Category> Categories { get; set; }
            public DbSet<Product> Products { get; set; }
        }
    }
    
    

Esse código adiciona o namespace System.Data.Entity para que você possa ter acesso ao core de todas as funcionalidades do Entity Framework, que inclui a capacidade de consultar, inserir, atualizar, e deletar dados trabalhando com objetos fortemente tipados.

A classe ProductContext representa o contexto da base de dados do Entity Framework, que manipula a busca, armazenamento, e atualização das instâncias da classe Product na base de dados. A classe ProductContext deriva da classe base DbContext fornecido pelo Entity Framework.

4 Classe Inicializadora

Será necessário executar alguma lógica customizada para inicializar a base de dados na primeira vez que o context é usado. Isso permitirá alimentar os dados a serem adicionados na base de dados para que você possa imediatamente exibir produtos e categorias.

Esse procedimento adiciona uma nova classe inicializadora em C# na pasta Models.

  1. Crie outra classe na pasta Models e nomeie como ProductDatabaseInitializer.cs.
  2. Substitua o código padrão contido na classe pelo seguinte:
  3. 
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Data.Entity;
    
    namespace WingtipToys.Models
    {
        public class ProductDatabaseInitializer : DropCreateDatabaseIfModelChanges<ProductContext>
        {
            protected override void Seed(ProductContext context)
            {
                GetCategories().ForEach(c => context.Categories.Add(c));
                GetProducts().ForEach(p => context.Products.Add(p));
            }
    
            private static List<Category> GetCategories()
            {
                var categories = new List<Category> {
                    new Category
                    {
                        CategoryID = 1,
                        CategoryName = "Cars"
                    },
                    new Category
                    {
                        CategoryID = 2,
                        CategoryName = "Planes"
                    },
                    new Category
                    {
                        CategoryID = 3,
                        CategoryName = "Trucks"
                    },
                    new Category
                    {
                        CategoryID = 4,
                        CategoryName = "Boats"
                    },
                    new Category
                    {
                        CategoryID = 5,
                        CategoryName = "Rockets"
                    }
                };
    
                return categories;
            }
    
            private static List<Product> GetProducts()
            {
                var products = new List<Product> {
                    new Product
                    {
                        ProductID = 1,
                        ProductName = "Convertible Car",
                        Description = "This convertible car is fast! The engine is powered by a neutrino based battery (not included)." + 
                                      "Power it up and let it go!", 
                        ImagePath="carconvert.png",
                        UnitPrice = 22.50,
                        CategoryID = 1
                   },
                    new Product 
                    {
                        ProductID = 2,
                        ProductName = "Old-time Car",
                        Description = "There's nothing old about this toy car, except it's looks. Compatible with other old toy cars.",
                        ImagePath="carearly.png",
                        UnitPrice = 15.95,
                         CategoryID = 1
                   },
                    new Product
                    {
                        ProductID = 3,
                        ProductName = "Fast Car",
                        Description = "Yes this car is fast, but it also floats in water.",
                        ImagePath="carfast.png",
                        UnitPrice = 32.99,
                        CategoryID = 1
                    },
                    new Product
                    {
                        ProductID = 4,
                        ProductName = "Super Fast Car",
                        Description = "Use this super fast car to entertain guests. Lights and doors work!",
                        ImagePath="carfaster.png",
                        UnitPrice = 8.95,
                        CategoryID = 1
                    },
                    new Product
                    {
                        ProductID = 5,
                        ProductName = "Old Style Racer",
                        Description = "This old style racer can fly (with user assistance). Gravity controls flight duration." + 
                                      "No batteries required.",
                        ImagePath="carracer.png",
                        UnitPrice = 34.95,
                        CategoryID = 1
                    },
                    new Product
                    {
                        ProductID = 6,
                        ProductName = "Ace Plane",
                        Description = "Authentic airplane toy. Features realistic color and details.",
                        ImagePath="planeace.png",
                        UnitPrice = 95.00,
                        CategoryID = 2
                    },
                    new Product
                    {
                        ProductID = 7,
                        ProductName = "Glider",
                        Description = "This fun glider is made from real balsa wood. Some assembly required.",
                        ImagePath="planeglider.png",
                        UnitPrice = 4.95,
                        CategoryID = 2
                    },
                    new Product
                    {
                        ProductID = 8,
                        ProductName = "Paper Plane",
                        Description = "This paper plane is like no other paper plane. Some folding required.",
                        ImagePath="planepaper.png",
                        UnitPrice = 2.95,
                        CategoryID = 2
                    },
                    new Product
                    {
                        ProductID = 9,
                        ProductName = "Propeller Plane",
                        Description = "Rubber band powered plane features two wheels.",
                        ImagePath="planeprop.png",
                        UnitPrice = 32.95,
                        CategoryID = 2
                    },
                    new Product
                    {
                        ProductID = 10,
                        ProductName = "Early Truck",
                        Description = "This toy truck has a real gas powered engine. Requires regular tune ups.",
                        ImagePath="truckearly.png",
                        UnitPrice = 15.00,
                        CategoryID = 3
                    },
                    new Product
                    {
                        ProductID = 11,
                        ProductName = "Fire Truck",
                        Description = "You will have endless fun with this one quarter sized fire truck.",
                        ImagePath="truckfire.png",
                        UnitPrice = 26.00,
                        CategoryID = 3
                    },
                    new Product
                    {
                        ProductID = 12,
                        ProductName = "Big Truck",
                        Description = "This fun toy truck can be used to tow other trucks that are not as big.",
                        ImagePath="truckbig.png",
                        UnitPrice = 29.00,
                        CategoryID = 3
                    },
                    new Product
                    {
                        ProductID = 13,
                        ProductName = "Big Ship",
                        Description = "Is it a boat or a ship. Let this floating vehicle decide by using its " + 
                                      "artifically intelligent computer brain!",
                        ImagePath="boatbig.png",
                        UnitPrice = 95.00,
                        CategoryID = 4
                    },
                    new Product
                    {
                        ProductID = 14,
                        ProductName = "Paper Boat",
                        Description = "Floating fun for all! This toy boat can be assembled in seconds. Floats for                   minutes!" + 
                                      "Some folding required.",
                        ImagePath="boatpaper.png",
                        UnitPrice = 4.95,
                        CategoryID = 4
                    },
                    new Product
                    {
                        ProductID = 15,
                        ProductName = "Sail Boat",
                        Description = "Put this fun toy sail boat in the water and let it go!",
                        ImagePath="boatsail.png",
                        UnitPrice = 42.95,
                        CategoryID = 4
                    },
                    new Product
                    {
                        ProductID = 16,
                        ProductName = "Rocket",
                        Description = "This fun rocket will travel up to a height of 200 feet.",
                        ImagePath="rocket.png",
                        UnitPrice = 122.95,
                        CategoryID = 5
                    }
                };
    
                return products;
            }
        }
    }
    
    

Como você pode ver no código acima, quando a base de dados é criada e inicializada, a propriedade Seed é substituída e definida. Quando a propriedade Seed é definida, os valores de categorias e produtos são usados para popular a base de dados. Se você tentar atualizar os dados alimentados modificando o código acima depois que a base de dados for criada, você não verá nenhuma atualização quando executar a aplicação Web. A razão é que o código acima usa uma implementação da classe DropCreateDatabaseIfModelChanges para reconhecer se o model foi alterado antes de resetar os dados alimentados. Se nenhuma alteração for feita às entity classes Category e Product, a base de dados não será reinicializada com os dados alimentados.

Nota: se você quisesse que a base de dados fosse recriada toda hora que a aplicação for executada, poderia usar a classe DropCreateDatabaseAlways ao invés da classe DropCreateDatabaseIfModelChanges. Entretanto para essa série de tutoriais, use a classe DropCreateDatabaseIfModelChanges.

Nesse ponto do tutorial, você terá uma pasta Models com quatro novas classes e uma classe padrão:

Figura 3 - Parte 3

5 Configurando a Aplicação para usar Data Model

Agora que você criou as classes que representam os dados, deve-se configurar a aplicação para usar as classes. No arquivo Global.asax, você adiciona código para inicializar o model. No arquivo Web.config você adiciona informação que diz a aplicação qual base de dados será usada para armazenar os dados que são representados pelas novas classes de dados. O arquivo Global.asax pode ser usado para manipular eventos ou métodos da aplicação. O arquivo Web.config permite que você controle a configuração de sua aplicação Web.

5.1 Atualizando o arquivo Global.asax

Para inicializar os data models quando a aplicação executar, você atualizará o manipulador Application_Start no arquivo Global.asax.

Nota: na Solution Explorer, você pode selecionar o arquivo Global.asax ou Global.asax.cs para editar o arquivo Global.asax.cs.

  1. Adicione o seguinte código no método Application_Start no arquivo Global.asax.cs.
  2. 
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Optimization;
    using System.Web.Routing;
    using System.Web.Security;
    using System.Web.SessionState;
    using System.Data.Entity;
    using WingtipToys.Models;
    
    namespace WingtipToys
    {
        public class Global : HttpApplication
        {
            void Application_Start(object sender, EventArgs e)
            {
                // Code that runs on application startup
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
    
                //Initialize the product database.
                Database.SetInitializer(new ProductDatabaseInitializer());
            }
        }
    }
    
    

Como mostrado no código acima, quando a aplicação iniciar, a aplicação especifica o inicializador que irá executar durante a primeira vez que o dado é acessado. Os namespaces adicionais (using System.Data.Entity e WingtipToys.Models) são necessários para acessar o objeto Database e o objeto ProductDatabaseInitializer.

5.2 Modificando o arquivo Web.config

Embora o Entity Framework Code First gerará uma base de dados para você num local padrão quando a base de dados é populada com dados, adicionar sua própria informação de conexão na sua aplicação te dá controle a localização da base de dados. Você especifica essa conexão da base de dados usando uma connection string no arquivo Web.config da aplicação na raíz do projeto. Adicionando uma nova connection string, você pode direcionar a localização da base de dados (wingtiptoys.mdf) para ser construída no diretório de dados da aplicação (App_Data), em vez de sua localização padrão. Fazer essa mudança permite que você encontre e inspecione posteriormente o arquivo da base de dados nesse tutorial.

  1. Na Solution Explorer, encontre e abra o arquivo Web.config.
  2. Adicione a connection string abaixo na seção do arquivo Web.config, como segue:
  3. 
    <connectionStrings>
        <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-WingtipToys-20140407092028.mdf;Initial Catalog=aspnet-WingtipToys-20140407092028;Integrated Security=True" providerName="System.Data.SqlClient" />
        <add name="WingtipToys" connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\wingtiptoys.mdf;Integrated Security=True" providerName="System.Data.SqlClient" />
      </connectionStrings>
    
    

Quando a aplicação for executada pela primeira vez, construirá a base de dados no local especificado pela connection string. Mas antes de executar a aplicação, vamos fazer o build da mesma.

6 Buildando a Aplicação

Para garantir que todas as classes e alterações da sua aplicação Web funcionaram, você deve buildar a aplicação.

  1. No menu Debug, selecione Build WingtipToys. A janela Output é exibida, e se tudo correu bem, você verá uma mensagem de sucesso.

Figura 4 - Parte 3

Se sua execução der erro, cheque os passos anteriores. A informação na janela Output indicará quais arquivos tem um problema e onde no arquivo uma mudança e requerida. Essa informação permitirá que você determine qual parte dos passos anteriores precisam ser revisados e corrigidos no seu projeto.

Sumário

Nesse tutorial você criou o modelo de dados, assim como, adicionou o código que será usado para inicializar e alimentar a base de dados. Você também configurou a aplicação para usar o modelo de dados quando a aplicação é executada.

No próximo tutorial, você atualizará a Interface de Usuário, adicionar navegação, e recuperar os dados da base de dados. Isso resultará na base de dados sendo automaticamente criada baseada em entity classes que você criou nesse tutorial.


O conteúdo desta página resulta da tradução do artigo Getting Started with ASP.NET 4.5 Web Forms – Create the Data Access Layer, escrito pelo autor Erik Reitan, originalmente presente no site do asp.net. A página correspondente pode ser conferida aqui.


2 Comentários

  1. Rodrigo disse:

    Gostei muito deste blog, parabens, estou aprendendo asp.net mvc, e gostaria de saber se poderia me dar uma ajuda se vocé poder, eu gostaria de criar um CRUD, mas na parte de editar e excluir apenas para usuarios que criou pode ter esta permissão,não qualquer pessoa venho lendo muito na net sobre isso e não achei algo de como posso estar fazendo isso. Obrigado e seu blog foi muito bem explicativo

  2. Estava precisando ver o Entity Framework no Visual Studio 2012.
    Excelente post!

Deixe uma resposta

Faça o login usando um destes métodos para comentar:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: