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:
- Uma versão recente do Visual Studio.
- O banco de dados do exemplo escolar.
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.
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.
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.