Compartilhar via


Procedimentos armazenados de CUD do designer

Esse passo a passo mostra como mapear as operações de CUD criação/inserção, atualização e exclusão de um tipo de entidade para procedimentos armazenados usando o Designer do Entity Framework (Designer do EF).  Por padrão, o Entity Framework gera automaticamente as instruções SQL para as operações de CUD, mas você também pode mapear procedimentos armazenados para essas operações.  

Observe que o Code First não dá suporte ao mapeamento para funções ou procedimentos armazenados. No entanto, você pode chamar funções ou procedimentos armazenados usando o método System.Data.Entity.DbSet.SqlQuery. Por exemplo:

var query = context.Products.SqlQuery("EXECUTE [dbo].[GetAllProducts]");

Considerações ao mapear as operações de CUD para Procedimentos Armazenados

Ao mapear as operações de CUD para procedimentos armazenados, as seguintes considerações se aplicam:

  • Se você estiver mapeando uma das operações de CUD para um procedimento armazenado, mapeie todas elas. Se você não mapear as três, as operações não mapeadas falharão se executadas e um UpdateException será gerado.
  • Você deve mapear todos os parâmetros do procedimento armazenado para as propriedades da entidade.
  • Se o servidor gerar o valor da chave primária para a linha inserida, você deverá mapear esse valor de volta para a propriedade de chave da entidade. No exemplo a seguir, o procedimento armazenado InsertPerson retorna a chave primária recém-criada como parte do conjunto de resultados do procedimento armazenado. A chave primária é mapeada para a chave de entidade (PersonID) usando o recurso <Adicionar associações de resultados> do Designer do EF.
  • As chamadas de procedimento armazenado são mapeadas individualmente com as entidades no modelo conceitual. Por exemplo, se você implementar uma hierarquia de herança em seu modelo conceitual e mapear os procedimentos armazenados de CUD para o Pai (base) e as entidades filho (derivadas), salvar as alterações Filho chamará apenas os procedimentos armazenados do Filho, ele não disparará as chamadas de procedimentos armazenados do Pai.

Pré-requisitos

Para concluir esta explicação passo a passo, será necessário:

Configurar o Projeto

  • Open Visual Studio 2012.
  • Selecione Arquivo-> Novo -> Projeto
  • No painel esquerdo, clique em Visual C#e selecione o modelo de Console.
  • Insira CUDSProcsSample como o nome.
  • Selecione OK.

Criar um modelo

  • Clique com o botão direito do mouse no nome do projeto no Gerenciador de Soluções e selecione Adicionar -> Novo Item.

  • Selecione Dados no menu à esquerda e selecione Modelo de Dados de Entidade ADO.NET no painel Modelos.

  • Insira CUDSProcs.edmx no nome do arquivo e clique em Adicionar.

  • Na caixa de diálogo Escolher conteúdos do modelo, selecione Gerar do banco de dados e, em seguida, clique em Próximo.

  • Clique em Nova Conexão. Na caixa de diálogo Propriedades da Conexão, insira o nome do servidor (por exemplo, (localdb)\mssqllocaldb), selecione o método de autenticação, digite Escolar como o nome do banco de dados e clique em OK. A caixa de diálogo Escolher a conexão de dados é atualizada com suas configurações de conexões de banco de dados.

  • Na caixa de diálogo Escolher objetos de banco de sados, no nó Tabelas, selecione a tabela Person.

  • Além disso, selecione os seguintes procedimentos armazenados no nó Funções e procedimentos armazenados: DeletePerson, InsertPerson e UpdatePerson.

  • A partir do Visual Studio 2012, o Designer do EF dá suporte à importação em massa de procedimentos armazenados. A opçãoImportar funções e procedimentos armazenados selecionados para o modelo de entidade está selecionada por padrão. Como nesse exemplo há procedimentos armazenados que inserem, atualizam e excluem tipos de entidade, você não irá importá-los e deve desmarcar essa caixa de seleção.

    Import S Procs

  • Clique em Concluir. O Designer do EF, que fornece uma superfície de design para editar seu modelo, é exibido.

Mapear a entidade Person para procedimentos armazenados

  • Clique com o botão direito do mouse no tipo de entidade Person e selecione Mapeamento de procedimento armazenado.

  • Os mapeamentos de procedimentos armazenados aparecem na janela Detalhes de mapeamento.

  • Clique em <Selecionar função de inserção>. O campo se torna uma lista suspensa dos procedimentos armazenados no modelo de armazenamento que podem ser mapeados para tipos de entidade no modelo conceitual. Selecione InsertPerson na lista suspensa.

  • Os mapeamentos padrão entre os parâmetros de procedimento armazenado e as propriedades da entidade são exibidos. Observe que as setas indicam a direção do mapeamento: os valores da propriedade são fornecidos para os parâmetros de procedimento armazenados.

  • Clique em <Adicionar associação de resultados>.

  • Digite NewPersonID, o nome do parâmetro retornado pelo procedimento armazenado InsertPerson. Certifique-se de não digitar espaços à esquerda ou à direita.

  • Pressione Enter.

  • Por padrão, NewPersonID é mapeado para a chave de entidade PersonID. Observe que uma seta indica a direção do mapeamento: o valor da coluna de resultado é fornecido para a propriedade.

    Mapping Details

  • Clique em <Selecionar função de atualização> e selecione UpdatePerson na lista suspensa resultante.

  • Os mapeamentos padrão entre os parâmetros de procedimento armazenado e as propriedades da entidade são exibidos.

  • Clique em <Selecionar função de exclusão> e selecione DeletePerson na lista suspensa resultante.

  • Os mapeamentos padrão entre os parâmetros de procedimento armazenado e as propriedades da entidade são exibidos.

As operações de inserção, atualização e exclusão do tipo de entidade Person agora são mapeadas para procedimentos armazenados.

Se você quiser habilitar a verificação de simultaneidade ao atualizar ou excluir uma entidade com procedimentos armazenados, use uma das seguintes opções:

  • Use um parâmetro OUTPUT para retornar o número de linhas afetadas do procedimento armazenado e marcar a caixa de seleção Parâmetro de linhas afetadas ao lado do nome do parâmetro. Se o valor retornado for zero quando a operação for chamada, um OptimisticConcurrencyException será gerado.
  • Marque a caixa de seleção Usar valor original ao lado de uma propriedade que você deseja usar para verificação de simultaneidade. Quando houver tentativa de atualização, o valor da propriedade que foi originalmente lida do banco de dados será usado ao gravar dados de volta no banco de dados. Se o valor não corresponder ao valor no banco de dados, um OptimisticConcurrencyException será gerado.

Usar o modelo

Abra o arquivo Program.cs em que o método Principal está definido. Adicione o código a seguir à função Principal.

O código cria um novo objeto Person, atualiza o objeto e, por fim, exclui o objeto.

    using (var context = new SchoolEntities())
    {
        var newInstructor = new Person
        {
            FirstName = "Robyn",
            LastName = "Martin",
            HireDate = DateTime.Now,
            Discriminator = "Instructor"
        }

        // Add the new object to the context.
        context.People.Add(newInstructor);

        Console.WriteLine("Added {0} {1} to the context.",
            newInstructor.FirstName, newInstructor.LastName);

        Console.WriteLine("Before SaveChanges, the PersonID is: {0}",
            newInstructor.PersonID);

        // SaveChanges will call the InsertPerson sproc.  
        // The PersonID property will be assigned the value
        // returned by the sproc.
        context.SaveChanges();

        Console.WriteLine("After SaveChanges, the PersonID is: {0}",
            newInstructor.PersonID);

        // Modify the object and call SaveChanges.
        // This time, the UpdatePerson will be called.
        newInstructor.FirstName = "Rachel";
        context.SaveChanges();

        // Remove the object from the context and call SaveChanges.
        // The DeletePerson sproc will be called.
        context.People.Remove(newInstructor);
        context.SaveChanges();

        Person deletedInstructor = context.People.
            Where(p => p.PersonID == newInstructor.PersonID).
            FirstOrDefault();

        if (deletedInstructor == null)
            Console.WriteLine("A person with PersonID {0} was deleted.",
                newInstructor.PersonID);
    }
  • Compile e execute o aplicativo. O programa produz a seguinte saída*

Observação

PersonID é gerado automaticamente pelo servidor, portanto, você provavelmente verá um número diferente*

Added Robyn Martin to the context.
Before SaveChanges, the PersonID is: 0
After SaveChanges, the PersonID is: 51
A person with PersonID 51 was deleted.

Se você estiver trabalhando com a versão Ultimate do Visual Studio, poderá usar o Intellitrace com o depurador para ver as instruções SQL que são executadas.

Debug With Intellitrace