EF Code First-Acessando Stored Procedures

Olá,

Vou iniciar este post informando que o Entity Framework Code First não tem suporte nativo para Stored Procedures, ainda!!!

Mas se não é suportado nativamente, então como é possível acessá-las ? Através do método SqlQuery() do contexto, mas existe um inconveniente: o acesso fica vinculado ao banco de dados, ou seja, para cada banco de dados o acesso é feito de uma maneira, mesmo porquê cada banco tem uma maneira específica de chamar e tratar os parâmetros das stored procedures.

Em nosso exemplo vamos demonstrar como acessar uma stored procedure do banco de dados NorthWind. A procedure que vamos utilizar é a CustOrderHist, que recebe como parâmetro o código do cliente e retorna os produtos e quantidades compradas pelo cliente.

Vamos então criar nosso projeto console no Visual Studio 2010 e já adicionar as referências para o EF CodeFirst, caso você não tenha o EF CodeFirst instalado em seu computador, pode baixá-lo aqui.

image

Para pegar o retorno da stored procedure, vamos criar uma classe que conterá os campos retornados:

   1: public class ProdutosPorCliente

   2: {

   3:     public string ProductName { get; set; }

   4:     public int Total { get; set; }

   5: }

Para obter o conteúdo da classe, você precisa verificar o que a stored procedure retorna e neste caso ela retorna os nomes dos produtos e a quantidade comprada.

Antes de criar nosso contexto, vamos criar o arquivo de configuração para a string de conexão, veja este post sobre strings de conexão.

   1: <?xml version="1.0" encoding="utf-8" ?>

   2: <configuration>

   3:   <connectionStrings>

   4:     <add name="Contexto" providerName="System.Data.SqlClient" connectionString="Data Source=(local);Initial Catalog=Northwind;Persist Security Info=True;User ID=teste;Password=teste;Pooling=False;MultipleActiveResultSets=true;" />

   5:   </connectionStrings>

   6: </configuration>

Agora vamos criar o nosso contexto e incluir a chamada para a stored procedure:

   1: class Contexto : DbContext

   2: {

   3:     public IEnumerable<ProdutosPorCliente> RetornaProdutosPorCliente(string codigoCliente)

   4:     {

   5:         SqlParameter parClienteID = new SqlParameter("@CustomerID", SqlDbType.Text);

   6:         parClienteID.Value = codigoCliente;

   7:  

   8:         return Database.SqlQuery<ProdutosPorCliente>("exec CustOrderHist @CustomerID", parClienteID);

   9:     }

  10: }

Veja que nosso contexto não possui as classes de dados, mas elas foram omitidas somente por uma questão didática.

O inconveniente aqui, como falamos no início é que a chamada da stored procedure fica vinculada ao banco de dados. No exemplo usamos SqlParameter() para criar o parâmetro, pois nosso banco de dados é SQL Server. Caso o banco seja diferente a classe de parâmetro muda.

Vamos agora ao exemplo para realizar a chamada ao método:

   1: static void Main(string[] args)

   2:         {

   3:             Contexto ctx = new Contexto();

   4:  

   5:             var retProc = ctx.RetornaProdutosPorCliente("VINET");

   6:  

   7:             foreach (var l in retProc)

   8:             {

   9:                 Console.WriteLine("{0} - {1}", l.ProductName, l.Total);

  10:             }

  11:         }

Veja que é bem simples, pois o método retorna um IEnumerable que pode ser percorrido por um foreach().

Espero que o exemplo seja útil, mas gostaria de deixar claro que este é somente um meio alternativo para acessar stored procedures.

Até a próxima,

Carlos dos Santos.

4 Comments


  1. Olá Carlos, primeiramente parabéns pelo blog. Muitas informações interessantes.
    Sou iniciante com as plataformas da Microsoft de programação, tanto de softwares/aplicativos como internet(sites etc).
    tenho utilizado WebMatrix, Expression Blend e o Visual Studio.
    Gostaria de tirar uma dúvida.
    Gosto de Tangram e tive a idéia de criar um WPF que permita o usuário jogar(hobby mesmo).
    No entanto utilizando apenas o Expression Blend consegui aplicar um “behavior” dragelement, mas não sei como habilitar rotate no momento de execução do WPF, devido ao principio de funcionalidade do jogo tangram que deve permitir rotacionar os triângulos e reposiciona-los.
    Andei procurando achei mas poucas sugestões.
    Gostaria de sua opinião e sugestão se possível

    Grato

    Reply

    1. Olá Lorenço,

      Obrigado pelos comentários. Sobre WPF dá uma olhada no site http://www.windowsclient.net que existem diversos tutoriais que podem te ajudar.

      []s,
      Carlos.

      Reply

  2. Olá, no caso de chamar um procedure pelo EF, no caso, de um update, os dados do contexto não são atualizados. Qual seria a maneira correta para atualizar o contexto?

    Reply

    1. Olá Silvio,

      Você pode fazer assim:
      context.Entry(seu_objeto).Reload();

      []s,

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Anti-spam: complete the taskWordPress CAPTCHA


This blog is kept spam free by WP-SpamFree.