Stored Procedures no Entity Framework

C# & ORM

Aqui vai um post sobre o uso de stored procedures no Entity Framework. Não vou entrar no mérito da importância de SPs ou se ORMs como o EF eliminam esta necessidade. Vou apenas me ater as funcionalidades e motivos de algumas estranhezas ao se falar em SPs no Entity Framework.


 

Introdução

Para este fim criei uma aplicação MVC Razor com um Banco e duas tabelas, Cliente e Compra. Como na imagem abaixo:

01

 

Agora vamos mapear o banco a ser trabalhado inserindo na pasta Models o modelo de dados. Clique com o botão direito e  selecione as opções Add > NewItem > ADO.NET Entity Data Model > Add. O próximo passo e apontar para o banco a ser mapeado, com já disse anteriormente, neste exemplo estaremos trabalhando com um banco local na aplicação. Após isto será apresentado a tela onde você vai selecionar os recursos do banco que serão mapeados:

02

 

Observe que estou selecionando duas SPs. Com este passo completo iremos obter o arquivo edmx e uma janela exibindo o modelo será aberta:

03

 

Analise do problema

Primeiro vamos observar o painel Model Browser:

04

 

É possível notar que nosso modelo edmx possuí dois nós de navegação. No segundo nó temos uma pasta chamada Stored Procedures e dentro deste diretório temos as duas procedures que selecionamos no momento da criação do modelo.

Neste ponto você “acha” que já é possível consumir as procedures mas não é o caso. Para que seja possível consumir estes procedimentos, é necessário associarmos nossas SPs como funções do modelo.

Por padrão, o Entity Framework realiza operações diretamente nas tabelas do banco de dados. Isso ocorre devido ao mapeamento entre os esquemas conceituais e de armazenamento. Para utilizarmos SPs devemos então alterar os esquemas de mapeamento.

Podemos fazer isso de duas maneiras: Criando uma função de importação no modelo conceitual que irá mapear a stored procedure ou mapear na mão… vamos ver apenas a primeira opção (pelo menos por agora).

 

A solução

Observe na figura acima que no primeiro nó do modelo conceitual temos uma pasta chamada Functions Imports e ela está vazia. Pois bem, é aqui que a magia vai acontecer.

O que iremos fazer agora é criar uma função para mapear a SP desejada.

Quando criamos uma função o EF cria um método correspondente dentro do ObjectContext mapeando a SP desejada. Neste momento estamos vinculando a execução deste procedimento ao nosso modelo conceitual. Neste momento também é possível definir o tipo de retorno.

Clique com o o botão direito em Function Imports > Add Function Import… Na janela seguinte você pode definir o nome da função, a SP a ser mapeada e o tipo de retorno, exatamente como a imagem abaixo:

10

Sobre os tipos de retorno:

  • None: Nenhum tipo de retorno;
  • Scalars: Retorna tipos específicos como Int32, Boolean, Binary etc;
  • Complex: Retorna um tipo coplexo. Este tipo possui propriedades correspondentes as colunas retornadas pela storede procedure. Este tipo é gerado automaticamente ao clicar no botão Create New Complex Type;
  • Entities: Retorna em uma entidade padrão do modelo.

 

Neste momento vou demonstrar a importação de uma SP que retorna um tipo Complex. O arquivo com o exemplo está disponível no fim do POST. A SP a ser importada é proc_ListarComprasDetalhadas. Vamos dar uma olhada em sua sintaxe:

11

 

Como podemos notar estou fazendo um INNER JOIN e retornando dados das duas tabelas. Ao importar a SP utilizo um retono do tipo Complex e o próprio EF cria um tipo correspondente.

05

 

Agora ao vamos importar a proc_BuscarComprasDoCliente. Esta retorna um tipo já mapeado pelo modelo conceitual, neste caso a entidade Compra. Sendo assim posso simplesmente apontar o tipo de retorno como Entities e selecionar a entidade correspondente. Vamos analisar a sintaxe da SP e a tela de importação correspondente:

12

06

 

Se observamos o painel Model Browser vamos perceber que nossas procedures foram mapeadas e que um novo tipo foi criado na pasta Complex Types como na imagem abaixo:

07

 

Deste momento em diante é possível consumir a função e trabalhar com o novo tipo de maneira simples:

09

 

Baixe aqui o exemplo utilizado neste POST!


Author's profile picture

Vitor is a computer scientist who is passionate about creating software that will positively change the world we live in.

MVP Azure - Cloud Architect - Data science enthusiast


4 minutes to read