Partilhar via


Parte 2: Criação dos Modelos de Domínio

por Rick Anderson

Descarregar Projeto Concluído

Adicionar Modelos

Existem três formas de abordar o Entity Framework:

  • Base de dados em primeiro lugar: Começas com uma base de dados e o Entity Framework gera o código.
  • Model-first: Começa-se com um modelo visual, e o Entity Framework gera tanto a base de dados como o código.
  • Código em primeiro lugar: Começas com código, e o Entity Framework gera a base de dados.

Estamos a usar a abordagem de código em primeiro lugar, por isso começamos por definir os nossos objetos de domínio como POCOs (objetos CLR comuns). Com a abordagem de código em primeiro lugar, os objetos de domínio não precisam de código adicional para suportar a camada da base de dados, como transações ou persistência. (Especificamente, não precisam de herdar da classe EntityObject .) Ainda podes usar anotações de dados para controlar como o Entity Framework cria o esquema da base de dados.

Como os POCOs não possuem propriedades extra que descrevam o estado da base de dados, podem ser facilmente serializados para JSON ou XML. No entanto, isso não significa que deva sempre expor os seus modelos Entity Framework diretamente aos clientes, como veremos mais adiante no tutorial.

Vamos criar os seguintes POCOs:

  • Produto
  • Encomenda
  • Detalhes do Pedido

Para criar cada classe, clique com o botão direito na pasta Models no Explorador de Soluções. No menu de contexto, selecione Adicionar e depois selecione Classe.

Captura de ecrã do menu Solutions Explorer para a pasta Models. O menu Adicionar está aberto e a opção de Classe está destacada.

Adicione uma Product classe com a seguinte implementação:

namespace ProductStore.Models
{
    using System.ComponentModel.DataAnnotations;

    public class Product
    {
        [ScaffoldColumn(false)]
        public int Id { get; set; }
        [Required]
        public string Name { get; set; }
        public decimal Price { get; set; }
        public decimal ActualCost { get; set; }
    }
}

Por convenção, o Entity Framework utiliza a Id propriedade como chave primária e mapeia-a para uma coluna de identidade na tabela da base de dados. Quando crias uma nova Product instância, não defines um valor para Id, porque a base de dados gera esse valor.

O atributo ScaffoldColumn indica ASP.NET MVC para saltar a Id propriedade ao gerar um formulário editor. O atributo Required é usado para validar o modelo. Especifica que a Name propriedade deve ser uma cadeia não vazia.

Adicione a Order classe:

namespace ProductStore.Models
{
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;

    public class Order
    {
        public int Id { get; set; }
        [Required]
        public string Customer { get; set; }

        // Navigation property
        public  ICollection<OrderDetail> OrderDetails { get; set; }
    }
}

Adicione a OrderDetail classe:

namespace ProductStore.Models
{
    public class OrderDetail
    {
        public int Id { get; set; }
        public int Quantity { get; set; }
        public int OrderId { get; set; }
        public int ProductId { get; set; }

        // Navigation properties
        public Product Product { get; set; }
        public Order Order { get; set; }
    }
}

Relações de Chave Externa

Uma encomenda contém muitos detalhes da encomenda, e cada detalhe da encomenda refere-se a um único produto. Para representar estas relações, a OrderDetail classe define propriedades nomeadas OrderId e ProductId. O Entity Framework irá inferir que estas propriedades representam chaves estrangeiras e adicionará restrições de chave estrangeira à base de dados.

Captura de ecrã dos menus do Visual Studio para as classes Orders, Products e OrderDetails.

As Order classes e OrderDetail também incluem propriedades de "navegação", que contêm referências aos objetos relacionados. Com uma encomenda, poderá navegar até aos produtos da encomenda seguindo as propriedades de navegação.

Compila o projeto agora. O Entity Framework utiliza reflexão para descobrir as propriedades dos modelos, pelo que requer um assembly compilado para criar o esquema da base de dados.

Configurar os Formatadores de Tipo de Mídia

Um formateador do tipo media é um objeto que serializa os seus dados quando a Web API escreve o corpo da resposta HTTP. Os formatadores incorporados suportam saída JSON e XML. Por defeito, ambos estes formateadores serializam todos os objetos por valor.

A serialização por valor cria um problema se um grafo objeto contiver referências circulares. É exatamente o caso das Order classes e, OrderDetail porque cada uma tem uma referência à outra. O formador segue as referências, escrevendo cada objeto por valor, e anda em círculos. Por isso, precisamos de mudar o comportamento padrão.

No Explorador de Soluções, expanda a pasta App_Start e abra o ficheiro chamado WebApiConfig.cs. Adicione o seguinte código à WebApiConfig classe:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        // New code:
        var json = config.Formatters.JsonFormatter;
        json.SerializerSettings.PreserveReferencesHandling =
            Newtonsoft.Json.PreserveReferencesHandling.Objects;

        config.Formatters.Remove(config.Formatters.XmlFormatter);
    }
}

Este código configura o formatador JSON para preservar referências de objetos e remove completamente o formatador XML do pipeline. (Podes configurar o formatador XML para preservar referências de objetos, mas dá um pouco mais de trabalho, e só precisamos de JSON para esta aplicação. Para mais informações, veja Tratamento de Referências de Objetos Circulares.)