Entity Framework Core - Chave primária composta
Tags: csharp, dotnet, sql
Published: 2021-07-15 00:15:36

## Um pouco sobre o Entity Framework Core

O Entity Framework Core é uma ferramenta ORM (Object-Relational Mapper) que mapeia objetos expostos em classes C# para entidades de um banco de dados. O Entity Framework Core dá suporte a consultas por meio do LINQ, controla as alterações nas entidades, atualizações e migrations (migrações) de schemas (esquemas) de banco de dados.

O Entity Framework está disponível a partir do Service Pack do .NET Framework em sua versão 3.5, no Visual Studio 2008. Desde então, vem ganhando várias atualizações e melhorias e tem se consolidado como principal ferramenta ORM para desenvolvimento de aplicações na plataforma .NET. Com a chegada do .NET Core, o Entity Framework naturalmente evoluiu para o Entity Framework Core (EF Core), recebendo diversas melhorias, e como esperado, tornou-se, assim como o .NET Framework, multiplataforma. Estando disponível para Windows, MacOS e GNU/Linux.

Você pode conferir todas as informações e documentação do Entity Framework Core no site oficial da ferramenta, através do link: [Documentação oficial do EF Core](https://docs.microsoft.com/pt-br/ef/).

## O que é uma chave primária composta
Uma chave primária composta é aquela criada com dois ou mais campos, ou seja, é a combinação de mais de uma coluna, e que desta maneira, passa a utilizar a junção dos dados dos dois campos indicados para compor um valor único, evitando assim o bloqueio por duplicidade. Com isso temos a garantia de que cada linha na tabela poderá ser identificada de forma única.

De maneira geral, utiliza-se a chave primária composta quando não existe um campo que possa ser usado para identificar as linhas de forma exclusiva, necessitando então que se tenha uma junção de dois ou mais campos para formar uma chave composta, ou então, quando não há a necessidade de se ter uma chave primária simples em uma tabela. Como é o caso da situação abaixo. 

> “Em um shopping são realizadas promoções, e nessas promoções são incluídos diversos produtos com um determinado desconto. Um mesmo produto pode pertencer a várias promoções diferentes, e uma única promoção obviamente poderá conter vários produtos diferentes.”

Para resolver esse problema, podemos criar uma tabela para produtos (**Products**), uma tabela para promoções (**Promotions**) e uma tabela de JOIN, para ser a tabela que irá realizar a junção das promoções com os produtos (**PromotionsProducts**) conforme exemplo ilustrado no diagrama ER (*Entidade Relacionamento*) abaixo:

![diagrama ER](https://i.postimg.cc/CM9DyDwY/1.png)

Perceba que na tabela PromotionProducts não possuímos nenhuma chave primária, apenas temos uma referência para o ID da tabela de produtos e uma referência para o ID da tabela de promoções. 

É em uma situação como essa que entra a chave primária composta. Por meio dela podemos, nesse exemplo, fazer uma chave primária composta com o ID da tabela de produtos, e o ID da tabela de promoções. Assim, cada linha dessa tabela será exclusiva, evitando duplicação. O código SQL para a criação dessa tabela está exemplificado abaixo:

![sql](https://i.postimg.cc/BnB11VHQ/2.png)

Isso é importante porque em casos onde utilizamos ferramentas ORM, como o Entity Framework Core, por exemplo, é importante termos uma chave primária para cada entidade que iremos mapear.

## Chave primária composta no Entity Framework Core
Para podermos utilizar as chaves primárias compostas no Entity Framework Core, devemos adicionar uma sobrescrita ao método do próprio Entity Framework Core **OnModelCreating** na classe de contexto da nossa aplicação. 

Esse método é executado no evento de criação do modelo da nossa aplicação. Nele, podemos fazer algumas configurações para que sempre sejam executadas antes do evento de criação do modelo começar. Podemos adicionar o seguinte código na classe de contexto:

![context class](https://i.postimg.cc/VNs09WW9/3.png)

Dessa forma estamos indicando ao Entity Framework Core que a nossa Entidade **PromotionProduct** possui uma chave primária composta pelos valores de **PromotionID** e **ProductID**.

Criamos assim uma relação muitos-para-muitos, onde podemos ter a classe product indicando que um produto pode estar em muitas promoções:

![product](https://i.postimg.cc/x12z82k4/4.png)

Teremos também a nossa classe de promoções, onde nela estamos informando que possuímos muitos produtos para cada promoção:

![promotion](https://i.postimg.cc/sDSW3X2W/5.png)

E na nossa classe de JOIN teremos uma ligação de muitas promoções e muitos produtos:

![join class](https://i.postimg.cc/JhTDpHpf/6.png)

Fechamos assim este artigo. Muito obrigado por ter lido até aqui.
Até o próximo.