Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
por Scott Mitchell
Em tutoriais anteriores, aprendemos como o controle ObjectDataSource permitia inserir, atualizar e excluir dados. O controle SqlDataSource suporta as mesmas operações, mas a abordagem é diferente, e este tutorial mostra como configurar o SqlDataSource para inserir, atualizar e excluir dados.
Introdução
Conforme discutido em Uma visão geral da inserção, atualização e exclusão, o controle GridView fornece recursos internos de atualização e exclusão, enquanto os controles DetailsView e FormView incluem suporte à inserção juntamente com a funcionalidade de edição e exclusão. Esses recursos de modificação de dados podem ser conectados diretamente a um controle de fonte de dados sem que uma linha de código precise ser escrita. Uma visão geral da inserção, atualização e exclusão examinada usando o ObjectDataSource para facilitar a inserção, atualização e exclusão com os controles GridView, DetailsView e FormView. Como alternativa, o SqlDataSource pode ser usado no lugar do ObjectDataSource.
Lembre-se de que, para dar suporte à inserção, atualização e exclusão, com o ObjectDataSource precisávamos especificar os métodos de camada de objeto a serem invocados para executar a ação de inserção, atualização ou exclusão. Com o SqlDataSource, precisamos fornecer INSERTUPDATE, e DELETE instruções SQL (ou procedimentos armazenados) para executar. Como veremos neste tutorial, essas instruções podem ser criadas manualmente ou podem ser geradas automaticamente pelo assistente Configurar Fonte de Dados do SqlDataSource.
Observação
Como já discutimos os recursos de inserção, edição e exclusão dos controles GridView, DetailsView e FormView, este tutorial se concentrará na configuração do controle SqlDataSource para dar suporte a essas operações. Se você precisar aprimorar a implementação desses recursos no GridView, DetailsView e FormView, retorne aos tutoriais Edição, inserção e exclusão de dados, começando com Uma visão geral da inserção, atualização e exclusão.
Etapa 1: Especificando instruções INSERT, UPDATE e DELETE
Como vimos nos dois tutoriais anteriores, para recuperar dados de um controle SqlDataSource, precisamos definir duas propriedades:
-
ConnectionString, que especifica para que base de dados enviar a consulta, e -
SelectCommand, que especifica a instrução SQL ad-hoc ou o nome do procedimento armazenado a ser executado para retornar os resultados.
Para SelectCommand valores com parâmetros, os valores de parâmetro são especificados por meio da coleção SqlDataSource e SelectParameters podem incluir valores codificados, valores de origem de parâmetros comuns (campos querystring, variáveis de sessão, valores de controle da Web e assim por diante) ou podem ser atribuídos programaticamente. Quando o método de controle SqlDataSource é Select() invocado programaticamente ou automaticamente de um controle da Web de dados, uma conexão com o banco de dados é estabelecida, os valores de parâmetro são atribuídos à consulta e o comando é transferido para o banco de dados. Os resultados são retornados como um DataSet ou DataReader, dependendo do valor da propriedade s DataSourceMode do controle.
Junto com a seleção de dados, o controle SqlDataSource pode ser usado para inserir, atualizar e excluir dados fornecendo INSERTinstruções , UPDATEe DELETE SQL da mesma maneira. Basta atribuir as InsertCommandinstruções , UpdateCommand, e DeleteCommand propriedades , INSERTUPDATE, e DELETE SQL para executar. Se as instruções tiverem parâmetros (como na maioria das vezes terão), inclua-as InsertParametersnas coleções , UpdateParameterse DeleteParameters .
Depois que um InsertCommand, UpdateCommand, ou DeleteCommand valor tiver sido especificado, a opção Habilitar Inserção, Habilitar Edição ou Habilitar Exclusão na marca inteligente do controle da Web de dados correspondente ficará disponível. Para ilustrar isso, vamos pegar um exemplo da página que criamos no tutorial Querying.aspx aumentá-lo para incluir recursos de exclusão.
Comece abrindo as InsertUpdateDelete.aspx páginas e Querying.aspx da SqlDataSource pasta. No Designer na Querying.aspx página, selecione SqlDataSource e GridView no primeiro exemplo (os ProductsDataSource controles and GridView1 ). Depois de selecionar os dois controles, vá para o menu Editar e escolha Copiar (ou apenas pressione Ctrl+C). Em seguida, vá para o Designer de InsertUpdateDelete.aspx e cole nos controles. Depois de mover os dois controles para InsertUpdateDelete.aspxo , teste a página em um navegador. Você deve ver os valores das ProductIDcolunas , ProductNamee UnitPrice para todos os registros na Products tabela do banco de dados.
Figura 1: Todos os produtos estão listados, ordenados por ProductID (Clique para visualizar a imagem em tamanho real)
Adicionando as propriedades DeleteCommand e DeleteParameters do SqlDataSource
Neste ponto, temos um SqlDataSource que simplesmente retorna todos os registros da Products tabela e um GridView que processa esses dados. Nosso objetivo é estender este exemplo para permitir que o usuário exclua produtos por meio do GridView. Para fazer isso, precisamos especificar valores para o controle SqlDataSource s e DeleteCommand propriedades eDeleteParameters, em seguida, configurar o GridView para dar suporte à exclusão.
As DeleteCommand propriedades e DeleteParameters podem ser especificadas de várias maneiras:
- Através da sintaxe declarativa
- Na janela Propriedades no Designer
- Na tela Especificar uma instrução SQL personalizada ou procedimento armazenado no assistente Configurar Fonte de Dados
- Através do botão Avançado na tela Especificar colunas de uma tabela de exibição no assistente Configurar Fonte de Dados, que realmente gerará automaticamente a instrução SQL e a
DELETEcoleção de parâmetros usados nasDeleteCommandpropriedades eDeleteParameters
Examinaremos como ter a DELETE instrução criada automaticamente na Etapa 2. Por enquanto, vamos usar a janela Propriedades no Designer, embora o assistente Configurar Fonte de Dados ou a opção de sintaxe declarativa funcionem tão bem.
No Designer em , clique em InsertUpdateDelete.aspx SqlDataSource e, em ProductsDataSourceseguida, abra a janela Propriedades (no menu Exibir, escolha a janela Propriedades ou simplesmente pressione F4). Selecione a propriedade DeleteQuery, que exibirá um conjunto de reticências.
Figura 2: Selecione a propriedade DeleteQuery na janela Properties
Observação
O SqlDataSource não tem uma propriedade DeleteQuery. Em vez disso, DeleteQuery é uma combinação das propriedades e DeleteCommand e só é listado DeleteParameters na janela Propriedades ao exibir a janela através do Designer. Se você estiver olhando para a janela Propriedades na visualização Código-fonte, encontrará a DeleteCommand propriedade.
Clique nas reticências na propriedade DeleteQuery para abrir a caixa de diálogo Command and Parameter Editor (consulte a Figura 3). Nessa caixa de diálogo, você pode especificar a DELETE instrução SQL e especificar os parâmetros. Insira a seguinte consulta na caixa de texto do DELETE comando (manualmente ou usando o Construtor de Consultas, se preferir):
DELETE FROM Products
WHERE ProductID = @ProductID
Em seguida, clique no botão Atualizar parâmetros para adicionar o @ProductID parâmetro à lista de parâmetros abaixo.
@ProductID adicionado à lista de parâmetros de comando DELETE." />
Figura 3: Selecione a propriedade DeleteQuery na janela Properties (Clique para visualizar a imagem em tamanho real)
Não forneça um valor para este parâmetro (deixe sua fonte de parâmetro em Nenhum ). Depois de adicionarmos suporte de exclusão ao GridView, o GridView fornecerá automaticamente esse valor de parâmetro, usando o valor de sua DataKeys coleção para a linha cujo botão Excluir foi clicado.
Observação
O nome do DELETE parâmetro usado na consulta deve ser o mesmo que o DataKeyNames nome do valor em GridView, DetailsView ou FormView. Ou seja, o DELETE parâmetro na instrução é nomeado @ProductID propositalmente (em vez de, digamos, ), porque o nome da coluna da chave primária na tabela Products (e, portanto, @IDo valor DataKeyNames no GridView) é ProductID.
Se o nome e DataKeyNames o valor do parâmetro não corresponderem, o GridView não poderá atribuir automaticamente ao parâmetro o valor da DataKeys coleção.
Depois de inserir as informações relacionadas à exclusão na caixa de diálogo Editor de Comandos e Parâmetros, clique em OK e vá para a visualização Código-fonte para examinar a marcação declarativa resultante:
<asp:SqlDataSource ID="ProductsDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand=
"SELECT [ProductID], [ProductName], [UnitPrice] FROM [Products]"
DeleteCommand="DELETE FROM Products WHERE ProductID = @ProductID">
<DeleteParameters>
<asp:Parameter Name="ProductID" />
</DeleteParameters>
</asp:SqlDataSource>
Observe a adição da propriedade, DeleteCommand bem como a <DeleteParameters> seção e o objeto Parameter chamado productID.
Configurando o GridView para exclusão
Com a DeleteCommand propriedade adicionada, a marca inteligente do GridView agora contém a opção Ativar exclusão. Vá em frente e marque esta caixa de seleção. Conforme discutido em Uma visão geral da inserção, atualização e exclusão, isso faz com que o GridView adicione um CommandField com sua ShowDeleteButton propriedade definida como true. Como mostra a Figura 4, quando a página é visitada através de um navegador, um botão Delete é incluído. Teste esta página excluindo alguns produtos.
Figura 4: Cada linha GridView agora inclui um botão Delete (Clique para visualizar a imagem em tamanho real)
Ao clicar em um botão Delete, ocorre um postback, o GridView atribui ao ProductID parâmetro o DataKeys valor da coleção para a linha cujo botão Delete foi clicado e invoca o método s SqlDataSource Delete() . O controle SqlDataSource, em seguida, se conecta ao banco de dados e executa a DELETE instrução. Em seguida, o GridView se liga novamente ao SqlDataSource, voltando e exibindo o conjunto atual de produtos (que não inclui mais o registro recém-excluído).
Observação
Como o GridView usa sua DataKeys coleção para preencher os parâmetros SqlDataSource, é vital que a propriedade GridView s DataKeyNames seja definida como a(s) coluna(s) que constituem a chave primária e que o SqlDataSource s SelectCommand retorne essas colunas. Além disso, é importante que o nome do parâmetro no SqlDataSource s DeleteCommand seja definido como @ProductID. Se a DataKeyNames propriedade não estiver definida ou o parâmetro não for nomeado @ProductsID, clicar no botão Excluir causará um postback, mas não excluirá nenhum registro.
A Figura 5 mostra graficamente essa interação. Consulte novamente o tutorial Examinando os eventos associados à inserção, atualização e exclusão para obter uma discussão mais detalhada sobre a cadeia de eventos associados à inserção, atualização e exclusão de um controle da Web de dados.
Figura 5: Clicar no botão Delete no GridView invoca o método SqlDataSource s Delete()
Etapa 2: Gerando automaticamente as instruções INSERT, UPDATE e DELETE
Conforme a Etapa 1 examinada, INSERT, UPDATEe DELETE as instruções SQL podem ser especificadas através da janela Propriedades ou da sintaxe declarativa do controle. No entanto, essa abordagem requer que escrevamos manualmente as instruções SQL manualmente, o que pode ser monótono e propenso a erros. Felizmente, o assistente Configurar Fonte de Dados fornece uma opção para que as INSERTinstruções , UPDATEe e DELETE sejam geradas automaticamente ao usar as colunas Especificar de uma tabela de exibição.
Vamos explorar esta opção de geração automática. Adicione um DetailsView ao Designer e InsertUpdateDelete.aspx defina sua ID propriedade como ManageProducts. Em seguida, na marca inteligente DetailsView, escolha criar uma nova fonte de dados e criar um SqlDataSource chamado ManageProductsDataSource.
Figura 6: Criar um novo SqlDataSource nomeado ManageProductsDataSource (Clique para exibir a imagem em tamanho real)
No assistente Configurar Fonte de Dados, opte por usar a NORTHWINDConnectionString cadeia de conexão e clique em Avançar. Na tela Configurar a instrução Selecionar, deixe o botão de opção Especificar colunas de uma tabela ou exibição selecionado e escolha a Products tabela na lista suspensa. Selecione as ProductIDcolunas , ProductName, UnitPricee na Discontinued lista de caixas de seleção.
Figura 7: Usando a tabela, retorne as colunas , Products, ProductIDe ProductName (UnitPriceDiscontinuedimagem em tamanho real)
Para gerar INSERTautomaticamente , UPDATEe DELETE instruções com base na tabela e colunas selecionadas, clique no botão Avançado e marque a caixa de seleção Gerar INSERT, UPDATEe DELETE instruções.
Figura 8: Marque a caixa de seleção Gerar INSERT, UPDATEe DELETE instruções
A caixa de seleção Gerar INSERT, UPDATEe instruções DELETE só poderá ser marcada se a tabela selecionada tiver uma chave primária e a coluna (ou colunas) da chave primária estiver incluída na lista de colunas retornadas. A caixa de seleção Usar simultaneidade otimista, que se torna selecionável assim que a caixa de seleção Gerar INSERT, UPDATEe DELETE instruções for marcada, aumentará as WHERE cláusulas nas UPDATE instruções e DELETE resultantes para fornecer controle de simultaneidade otimista. Por enquanto, deixe esta caixa de seleção desmarcada; examinaremos a simultaneidade otimista com o controle SqlDataSource no próximo tutorial.
Depois de marcar a caixa de seleção Gerar INSERT, UPDATEe DELETE instruções, clique em OK para retornar à tela Configurar Instrução de Seleção, clique em Avançar e, em seguida, em Concluir, para concluir o assistente Configurar Fonte de Dados. Ao concluir o assistente, o Visual Studio adicionará BoundFields ao DetailsView para as ProductIDcolunas , ProductNamee UnitPrice e um CheckBoxField para a Discontinued coluna. Na marca inteligente DetailsView, marque a opção Ativar paginação para que o usuário que visita esta página possa percorrer os produtos. Limpe também as s e Width propriedades de Height DetailsView.
Observe que a marca inteligente tem as opções Habilitar inserção, Habilitar edição e Habilitar exclusão disponíveis. Isso ocorre porque o SqlDataSource contém valores para seu InsertCommand, UpdateCommand, e DeleteCommand, como mostra a sintaxe declarativa a seguir:
<asp:DetailsView ID="ManageProducts" runat="server" AllowPaging="True"
AutoGenerateRows="False" DataKeyNames="ProductID"
DataSourceID="ManageProductsDataSource" EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductID" HeaderText="ProductID"
InsertVisible="False" ReadOnly="True" SortExpression="ProductID" />
<asp:BoundField DataField="ProductName" HeaderText="ProductName"
SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
<asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
SortExpression="Discontinued" />
</Fields>
</asp:DetailsView>
<asp:SqlDataSource ID="ManageProductsDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
DeleteCommand=
"DELETE FROM [Products] WHERE [ProductID] = @ProductID"
InsertCommand=
"INSERT INTO [Products] ([ProductName], [UnitPrice], [Discontinued])
VALUES (@ProductName, @UnitPrice, @Discontinued)"
SelectCommand=
"SELECT [ProductID], [ProductName], [UnitPrice], [Discontinued]
FROM [Products]"
UpdateCommand=
"UPDATE [Products] SET [ProductName] = @ProductName,
[UnitPrice] = @UnitPrice, [Discontinued] = @Discontinued
WHERE [ProductID] = @ProductID">
<DeleteParameters>
<asp:Parameter Name="ProductID" Type="Int32" />
</DeleteParameters>
<UpdateParameters>
<asp:Parameter Name="ProductName" Type="String" />
<asp:Parameter Name="UnitPrice" Type="Decimal" />
<asp:Parameter Name="Discontinued" Type="Boolean" />
<asp:Parameter Name="ProductID" Type="Int32" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="ProductName" Type="String" />
<asp:Parameter Name="UnitPrice" Type="Decimal" />
<asp:Parameter Name="Discontinued" Type="Boolean" />
</InsertParameters>
</asp:SqlDataSource>
Observe como o controle SqlDataSource teve valores definidos automaticamente para suas InsertCommandpropriedades , UpdateCommande DeleteCommand . O conjunto de colunas referenciadas InsertCommand nas propriedades e UpdateCommand baseia-se nas SELECT da instrução. Ou seja, em vez de ter todas as colunas Produtos no e InsertCommand, existem apenas as colunas especificadas no UpdateCommand (menos SelectCommand, que é omitido porque é uma ProductID, cujo valor não pode ser alterado quando editado IDENTITY e que é atribuído automaticamente ao inserir). Além disso, para cada parâmetro no InsertCommand, UpdateCommande DeleteCommand propriedades existem parâmetros correspondentes no InsertParameters, UpdateParameters, e DeleteParameters coleções.
Para ativar os recursos de modificação de dados do DetailsView, marque as opções Habilitar inserção, Habilitar edição e Habilitar exclusão em sua marca inteligente. Isso adiciona um CommandField com suas ShowInsertButtonpropriedades , ShowEditButtone ShowDeleteButton definidas como true.
Visite a página em um navegador e observe os botões Editar, Excluir e Novo incluídos no DetailsView. Clicar no botão Editar transforma o DetailsView no modo de edição, que exibe cada BoundField cuja ReadOnly propriedade está definida como false (o padrão) como um TextBox e o CheckBoxField como uma caixa de seleção.
Figura 9: A interface de edição padrão do DetailsView (Clique para visualizar a imagem em tamanho real)
Da mesma forma, você pode excluir o produto selecionado atualmente ou adicionar um novo produto ao sistema. Como a InsertCommand instrução só funciona com as ProductNamecolunas , UnitPricee , as Discontinued outras colunas têm um ou NULL seu valor padrão atribuído pelo banco de dados após a inserção. Assim como com o ObjectDataSource, se estiver InsertCommand faltando qualquer coluna de tabela de banco de dados que não permita NULL s e não tenha um valor padrão, ocorrerá um erro SQL ao tentar executar a INSERT instrução.
Observação
As interfaces de inserção e edição do DetailsView carecem de qualquer tipo de personalização ou validação. Para adicionar controles de validação ou personalizar as interfaces, você precisa converter os BoundFields em TemplateFields. Consulte os tutoriais Adicionando controles de validação às interfaces de edição e inserção e Personalizando a interface de modificação de dados para obter mais informações.
Além disso, lembre-se de que, para atualizar e excluir, o DetailsView usa o valor do produto atual DataKey , que só estará presente se a DataKeyNames propriedade estiver configurada. Se a edição ou exclusão parecer não ter efeito, verifique se a DataKeyNames propriedade está definida.
Limitações da geração automática de instruções SQL
Como a opção Gerar INSERT, UPDATE, e DELETE instruções só está disponível ao selecionar colunas de uma tabela, para consultas mais complexas você terá que escrever suas próprias INSERTinstruções , UPDATEe DELETE como fizemos na Etapa 1. Geralmente, as instruções SQL SELECT usam JOIN s para trazer dados de volta de uma ou mais tabelas de pesquisa para fins de exibição (como trazer de volta o Categories campo s da CategoryName tabela ao exibir informações do produto). Ao mesmo tempo, podemos permitir que o usuário edite, atualize ou insira dados na tabela principal (Productsneste caso).
Embora as INSERTinstruções , UPDATE, e possam DELETE ser inseridas manualmente, considere a seguinte dica de economia de tempo. Inicialmente configure o SqlDataSource para que ele extraia dados apenas da Products tabela. Use o assistente Configurar Fonte de Dados s Especificar colunas de uma tabela ou tela de exibição para que você possa gerar automaticamente as INSERTinstruções , UPDATEe DELETE . Em seguida, depois de concluir o assistente, escolha configurar o SelectQuery na janela Propriedades (ou, alternativamente, volte para o assistente Configurar Fonte de Dados, mas use a opção Especificar uma instrução SQL personalizada ou procedimento armazenado). Em seguida, atualize a SELECT instrução para incluir a JOIN sintaxe. Essa técnica oferece os benefícios de economia de tempo das instruções SQL geradas automaticamente e permite uma instrução mais personalizada SELECT .
Outra limitação da geração automática das INSERTinstruções , UPDATEe é DELETE que as colunas nas INSERT instruções and UPDATE são baseadas nas colunas retornadas pela SELECT instrução. No entanto, talvez seja necessário atualizar ou inserir mais ou menos campos. Por exemplo, no exemplo da Etapa 2, talvez queiramos que o UnitPrice BoundField seja somente leitura. Nesse caso, ele não deve aparecer no UpdateCommand. Ou podemos definir o valor de um campo de tabela que não aparece no GridView. Por exemplo, ao adicionar um novo registro, podemos querer que o QuantityPerUnit valor seja definido como TODO .
Se essas personalizações forem necessárias, você precisará fazê-las manualmente, seja por meio da janela Propriedades, da opção Especificar uma instrução SQL personalizada ou procedimento armazenado no assistente ou por meio da sintaxe declarativa.
Observação
Ao adicionar parâmetros que não têm campos correspondentes no controle Web de dados, lembre-se de que esses valores de parâmetros precisarão ser atribuídos valores de alguma maneira. Esses valores podem ser: codificados diretamente no InsertCommand ou UpdateCommand; podem vir de alguma fonte pré-definida (querystring, estado da sessão, controles da Web na página e assim por diante) ou podem ser atribuídos programaticamente, como vimos no tutorial anterior.
Resumo
Para que os controles da Web de dados utilizem seus recursos internos de inserção, edição e exclusão, o controle da fonte de dados ao qual eles estão vinculados deve oferecer essa funcionalidade. Para o SqlDataSource, isso significa que INSERTas instruções , UPDATE, e DELETE SQL devem ser atribuídas às InsertCommandpropriedades , UpdateCommande DeleteCommand . Essas propriedades e as coleções de parâmetros correspondentes podem ser adicionadas manualmente ou geradas automaticamente por meio do assistente Configurar Fonte de Dados. Neste tutorial, examinamos ambas as técnicas.
Examinamos o uso da simultaneidade otimista com o ObjectDataSource no tutorial Implementando simultaneidade otimista. O controle SqlDataSource também fornece suporte de simultaneidade otimista. Conforme observado na Etapa 2, ao gerar automaticamente as INSERTinstruções , UPDATEe , o DELETE assistente oferece uma opção Usar simultaneidade otimista. Como veremos no próximo tutorial, usar simultaneidade otimista com o SqlDataSource modifica as WHERE cláusulas nas UPDATE instruções e DELETE para garantir que os valores das outras colunas não tenham sido alterados desde que os dados foram exibidos pela última vez na página.
Feliz Programação!
Sobre o Autor
Scott Mitchell, autor de sete livros sobre ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias Web da Microsoft desde 1998. Scott trabalha como consultor, formador e escritor independente. Seu último livro é Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Ele pode ser contatado em mitchell@4GuysFromRolla.com.