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
Neste tutorial, continuamos nossa análise do controle SqlDataSource e aprendemos como definir consultas parametrizadas. Os parâmetros podem ser especificados declarativa e programaticamente e podem ser extraídos de vários locais, como querystring, estado da sessão, outros controles e muito mais.
Introdução
No tutorial anterior, vimos como usar o controle SqlDataSource para recuperar dados diretamente de um banco de dados. Usando o assistente Configurar Fonte de Dados, poderíamos escolher o banco de dados e, em seguida: escolher as colunas a serem retornadas de uma tabela ou exibição; insira uma instrução SQL personalizada; ou utilizar um procedimento armazenado. Seja selecionando colunas de uma tabela ou exibição ou inserindo uma instrução SQL personalizada, a propriedade s SelectCommand do controle SqlDataSource recebe a instrução SQL SELECT ad-hoc resultante e é essa SELECT instrução que é executada quando o método s Select() SqlDataSource é invocado (programaticamente ou automaticamente a partir de um controle Web de dados).
As instruções SQL SELECT usadas nas demonstrações do tutorial anterior não tinham WHERE cláusulas. Em uma SELECT declaração, a WHERE cláusula pode ser usada para limitar os resultados retornados. Por exemplo, para exibir os nomes de produtos que custam mais de US $ 50,00, podemos usar a seguinte consulta:
SELECT ProductName
FROM Products
WHERE UnitPrice > 50.00
Normalmente, os valores usados em uma WHERE cláusula são determinados por alguma fonte externa, como um valor querystring, uma variável de sessão ou entrada do usuário de um controle da Web na página. Idealmente, tais entradas são especificadas através do uso de parâmetros. Com o Microsoft SQL Server, os parâmetros são indicados usando @parameterName, como em:
SELECT ProductName
FROM Products
WHERE UnitPrice > @Price
O SqlDataSource oferece suporte a consultas parametrizadas, tanto para instruções SELECTquanto para INSERT , UPDATEe DELETE instruções. Além disso, os valores dos parâmetros podem ser extraídos automaticamente de uma variedade de fontes, a querystring, o estado da sessão, os controles na página e assim por diante, ou podem ser atribuídos programaticamente. Neste tutorial, veremos como definir consultas parametrizadas, bem como especificar os valores dos parâmetros declarativa e programaticamente.
Observação
No tutorial anterior, comparamos o ObjectDataSource, que tem sido nossa ferramenta de escolha nos primeiros 46 tutoriais, com o SqlDataSource, observando suas semelhanças conceituais. Estas semelhanças também se estendem aos parâmetros. Os parâmetros do ObjectDataSource são mapeados para os parâmetros de entrada dos métodos na camada de lógica de negócios. Com o SqlDataSource, os parâmetros são definidos diretamente dentro da consulta SQL. Ambos os controles têm coleções de parâmetros para seus Select()métodos , , Insert()Update()e Delete() ambos podem ter esses valores de parâmetro preenchidos a partir de fontes predefinidas (valores querystring, variáveis de sessão e assim por diante) ou atribuídos programaticamente.
Criando uma consulta parametrizada
O assistente Configurar Fonte de Dados do controle SqlDataSource oferece três caminhos para definir o comando a ser executado para recuperar registros de banco de dados:
- Ao selecionar as colunas de uma tabela ou vista existente,
- Inserindo uma instrução SQL personalizada, ou
- Ao escolher um procedimento armazenado
Ao selecionar colunas de uma tabela ou exibição existente, os parâmetros para a WHERE cláusula devem ser especificados por meio da caixa de diálogo Adicionar WHERE cláusula. Ao criar uma instrução SQL personalizada, no entanto, você pode inserir os parâmetros diretamente na WHERE cláusula (usando @parameterName para denotar cada parâmetro). Um procedimento armazenado consiste em uma ou mais instruções SQL, e essas instruções podem ser parametrizadas. Os parâmetros usados nas instruções SQL, no entanto, devem ser passados como parâmetros de entrada para o procedimento armazenado.
Como a criação de uma consulta parametrizada depende de como o SqlDataSource s SelectCommand é especificado, vamos dar uma olhada em todas as três abordagens. Para começar, abra a página ParameterizedQueries.aspx na pasta SqlDataSource, arraste um controle SqlDataSource da Caixa de Ferramentas para o Designer e defina o seu ID como Products25BucksAndUnderDataSource. Em seguida, clique na ligação Configurar Fonte de Dados na etiqueta inteligente do controlo. Selecione o banco de dados a ser usado (NORTHWINDConnectionString) e clique em Avançar.
Etapa 1: Adicionando uma cláusula WHERE ao escolher as colunas de uma tabela ou exibição
Ao selecionar os dados a serem retornados do banco de dados com o controle SqlDataSource, o assistente Configurar Fonte de Dados nos permite simplesmente escolher as colunas a serem retornadas de uma tabela ou exibição existente (consulte a Figura 1). Isso cria automaticamente uma instrução SQL SELECT , que é o que é enviado para o banco de dados quando o método s SqlDataSource Select() é invocado. Como fizemos no tutorial anterior, selecione a tabela Produtos na lista suspensa e verifique as colunas ProductID, ProductName e UnitPrice.
Figura 1: Escolha as colunas a serem retornadas de uma tabela ou exibição (Clique para visualizar a imagem em tamanho real)
Para incluir uma cláusula WHERE na instrução SELECT, clique no botão WHERE, que exibe a caixa de diálogo Adicionar cláusula WHERE (consulte a Figura 2). Para adicionar um parâmetro para limitar os resultados retornados SELECT pela consulta, primeiro escolha a coluna pela qual filtrar os dados. Em seguida, escolha o operador a ser usado para filtragem (=, <, <=, >e assim por diante). Por fim, escolha a origem do valor do parâmetro s, como a partir da querystring ou do estado da sessão. Depois de configurar o parâmetro, clique no botão Adicionar para incluí-lo na SELECT consulta.
Para este exemplo, vamos retornar apenas os resultados em que o UnitPrice valor é menor ou igual a $25,00. Portanto, na lista suspensa de Coluna, escolha UnitPrice e na lista suspensa de Operador, escolha <=. Ao usar um valor de parâmetro codificado (como $25,00) ou se o valor do parâmetro for especificado programaticamente, selecione Nenhum na lista suspensa Origem. Em seguida, insira o valor do parâmetro codificado na caixa de texto Valor 25.00 e conclua o processo clicando no botão Adicionar.
Figura 2: Limitar os resultados retornados da caixa de diálogo Add WHERE Clause (Clique para visualizar a imagem em tamanho real)
Depois de adicionar o parâmetro, clique em OK para retornar ao assistente Configurar Fonte de Dados. A SELECT instrução na parte inferior do assistente agora deve incluir uma WHERE cláusula com um parâmetro chamado @UnitPrice:
SELECT [ProductID], [ProductName], [UnitPrice]
FROM [Products]
WHERE ([UnitPrice] <= @UnitPrice)
Observação
Se especificar várias condições na cláusula WHERE da caixa de diálogo Adicionar Cláusula WHERE, o assistente associa-as ao operador AND. Se precisar incluir um OR na cláusula WHERE (como WHERE UnitPrice <= @UnitPrice OR Discontinued = 1) terá de criar a instrução SELECT a partir da tela de instrução SQL personalizada.
Conclua a configuração do SqlDataSource (clique em Avançar e, em seguida, em Concluir) e inspecione a marcação declarativa de SqlDataSource. A marcação agora inclui uma <SelectParameters> coleção, que detalha as fontes para os parâmetros no SelectCommand.
<asp:SqlDataSource ID="Products25BucksAndUnderDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand=
"SELECT [ProductID], [ProductName], [UnitPrice]
FROM [Products] WHERE ([UnitPrice] <= @UnitPrice)">
<SelectParameters>
<asp:Parameter DefaultValue="25.00" Name="UnitPrice" Type="Decimal" />
</SelectParameters>
</asp:SqlDataSource>
Quando o método s SqlDataSource Select() é invocado, o valor do UnitPrice parâmetro (25.00) é aplicado ao @UnitPrice parâmetro no SelectCommand antes de ser enviado para o banco de dados. O resultado líquido é que apenas os produtos menores ou iguais a $25,00 são retornados da Products tabela. Para confirmar isso, adicione um GridView à página, vincule-o a essa fonte de dados e exiba a página por meio de um navegador. Você só deve ver os produtos listados que são menores ou iguais a $25,00, como a Figura 3 confirma.
Figura 3: Somente os produtos menores ou iguais a $25,00 são exibidos (Clique para visualizar a imagem em tamanho real)
Etapa 2: Adicionando parâmetros a uma instrução SQL personalizada
Ao adicionar uma instrução SQL personalizada, você pode inserir a WHERE cláusula explicitamente ou especificar um valor na célula Filtro do Construtor de Consultas. Para demonstrar isso, vamos exibir apenas os produtos em um GridView cujos preços são inferiores a um determinado limite. Comece adicionando um TextBox à ParameterizedQueries.aspx página para coletar esse valor de limite do usuário. Defina a propriedade TextBox s ID como MaxPrice. Adicione um controle Web Button e defina a sua Text propriedade como Exibir produtos correspondentes.
Em seguida, arraste um GridView para a página e, a partir de sua etiqueta inteligente, escolha criar um novo SqlDataSource chamado ProductsFilteredByPriceDataSource. No assistente Configurar Fonte de Dados, vá para a tela Especificar uma instrução SQL personalizada ou procedimento armazenado (consulte a Figura 4) e insira a seguinte consulta:
SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice
Depois de inserir a consulta (manualmente ou através do Construtor de Consultas), clique em Avançar.
Figura 4: Retornar somente os produtos menores ou iguais a um valor de parâmetro (Clique para visualizar a imagem em tamanho real)
Como a consulta inclui parâmetros, a próxima tela do assistente nos solicita a origem dos valores dos parâmetros. Escolha Control na lista suspensa Parameter source e MaxPrice (o valor do controle TextBox s ID ) na lista suspensa ControlID. Você também pode inserir um valor padrão opcional para usar no caso em que o usuário não inseriu nenhum texto na MaxPrice TextBox. Por enquanto, não insira um valor padrão.
Figura 5: A MaxPrice propriedade TextBox s Text é usada como a fonte do parâmetro (Clique para visualizar a imagem em tamanho real)
Conclua o assistente Configurar Fonte de Dados clicando em Avançar e, em seguida, em Concluir. A marcação declarativa para GridView, TextBox, Button e SqlDataSource segue:
Maximum price:
$<asp:TextBox ID="MaxPrice" runat="server" Columns="5" />
<asp:Button ID="DisplayProductsLessThanButton" runat="server"
Text="Display Matching Products" />
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
DataSourceID="ProductsFilteredByPriceDataSource" EnableViewState="False">
<Columns>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="Price"
HtmlEncode="False" DataFormatString="{0:c}"
SortExpression="UnitPrice" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="ProductsFilteredByPriceDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand=
"SELECT ProductName, UnitPrice
FROM Products WHERE UnitPrice <= @MaximumPrice">
<SelectParameters>
<asp:ControlParameter ControlID="MaxPrice" Name="MaximumPrice"
PropertyName="Text" />
</SelectParameters>
</asp:SqlDataSource>
Observe que o parâmetro dentro da seção SqlDataSource s <SelectParameters> é um ControlParameter, que inclui propriedades adicionais como ControlID e PropertyName. Quando o método SqlDataSource s Select() é invocado, o ControlParameter pega o valor da propriedade de controle da Web especificada e o atribui ao parâmetro correspondente no SelectCommand. Neste exemplo, a MaxPrice propriedade s Text é usada como o valor do @MaxPrice parâmetro.
Reserve um minuto para visualizar esta página através de um navegador. Ao visitar a página pela primeira vez ou sempre que o TextBox não tiver um valor, nenhum registro será exibido no MaxPrice GridView.
Figura 6: Nenhum registro é exibido quando a caixa de texto está vazia (MaxPrice imagem em tamanho real)
A razão pela qual nenhum produto é mostrado é porque, por padrão, uma cadeia de caracteres vazia para um valor de parâmetro é convertida em um valor de banco de dados NULL . Como a comparação de [UnitPrice] <= NULL sempre é avaliada como False, nenhum resultado é retornado.
Insira um valor na caixa de texto, como 5.00, e clique no botão Exibir produtos correspondentes. No postback, o SqlDataSource informa o GridView que uma de suas fontes de parâmetros foi alterada. Consequentemente, o GridView se liga novamente ao SqlDataSource, exibindo esses produtos menores ou iguais a $5,00.
Figura 7: Produtos menores ou iguais a US$ 5,00 são exibidos (Clique para visualizar a imagem em tamanho real)
Exibindo inicialmente todos os produtos
Em vez de não exibir nenhum produto quando a página é carregada pela primeira vez, podemos querer exibir todos os produtos. Uma maneira de listar todos os produtos sempre que o TextBox estiver vazio é definir o valor padrão do parâmetro para algum valor insanamente alto, como 1000000, já que é improvável que a MaxPrice Northwind Traders tenha estoque cujo preço unitário exceda $1.000.000. No entanto, esta abordagem é míope e pode não funcionar noutras situações.
Em tutoriais anteriores - Parâmetros Declarativos e A Filtragem Mestre/Detalhe com DropDownList, nos deparamos com um problema semelhante. Nossa solução lá foi colocar essa lógica na camada de lógica de negócios. Especificamente, a BLL examinou o valor de entrada e, se era NULL ou algum valor reservado, a chamada foi roteada para o método DAL que retornou todos os registros. Se o valor de entrada era um valor de filtragem normal, uma chamada era feita para o método DAL que executava uma instrução SQL que usava uma cláusula parametrizada WHERE com o valor fornecido.
Infelizmente, ignoramos a arquitetura ao usar o SqlDataSource. Em vez disso, precisamos personalizar a instrução SQL para obter de forma inteligente todos os registos se o parâmetro @MaximumPrice for NULL ou um valor reservado. Para este exercício, vamos tê-lo de modo que, se o @MaximumPrice parâmetro for igual a -1.0, então todos os registros devem ser retornados (-1.0 funciona como um valor reservado, uma vez que nenhum produto pode ter um valor negativo UnitPrice ). Para fazer isso, podemos usar a seguinte instrução SQL:
SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice OR @MaximumPrice = -1.0
Esta WHERE cláusula retorna todos os registros se o parâmetro for @MaximumPriceigual a -1.0 . Se o valor do parâmetro não for -1.0, somente os produtos cujo UnitPrice seja menor ou igual ao valor do parâmetro @MaximumPrice serão retornados. Ao definir o @MaximumPrice valor padrão do parâmetro como -1.0, no carregamento da primeira página (ou sempre que a MaxPrice TextBox estiver vazia), @MaximumPrice terá um valor de -1.0 e todos os produtos serão exibidos.
Figura 8: Agora todos os produtos são exibidos quando a caixa de texto está vazia (MaxPrice imagem em tamanho real)
Há algumas ressalvas a observar com esta abordagem. Primeiro, perceba que o tipo de dados do parâmetro s é inferido pelo seu uso na consulta SQL. Se alterar a WHERE cláusula de @MaximumPrice = -1.0 para @MaximumPrice = -1, em tempo de execução tratará o parâmetro como um inteiro. Se, em seguida, você tentar atribuir o MaxPrice TextBox a um valor decimal (como 5.00 ), ocorrerá um erro porque ele não pode converter 5.00 em um inteiro. Para corrigir isso, certifique-se de usar @MaximumPrice = -1.0 na cláusula WHERE ou, melhor ainda, defina a propriedade ControlParameter do objeto Type para Decimal.
Em segundo lugar, ao adicionar o OR @MaximumPrice = -1.0 à cláusula WHERE, o mecanismo de consulta não pode usar um índice em UnitPrice (supondo que exista), resultando assim numa verificação à tabela. Isso pode afetar o desempenho se houver um número suficientemente grande de registros na tabela Products. Uma abordagem melhor seria mover essa lógica para um procedimento armazenado onde uma IF instrução executaria uma SELECT consulta da Products tabela sem uma WHERE cláusula quando todos os registros precisam ser retornados ou uma cuja WHERE cláusula contém apenas os UnitPrice critérios, para que um índice possa ser usado.
Etapa 3: Criando e usando procedimentos armazenados parametrizados
Os procedimentos armazenados podem incluir um conjunto de parâmetros de entrada que podem ser usados na(s) instrução(ões) SQL(s) definida(s) no procedimento armazenado. Ao configurar o SqlDataSource para usar um procedimento armazenado que aceita parâmetros de entrada, esses valores de parâmetro podem ser especificados usando as mesmas técnicas que com instruções SQL ad-hoc.
Para ilustrar o uso de procedimentos armazenados no SqlDataSource, vamos criar um novo procedimento armazenado no banco de dados Northwind chamado GetProductsByCategory, que aceita um parâmetro chamado @CategoryID e retorna todas as colunas dos produtos cuja coluna CategoryID corresponde a @CategoryID. Para criar um procedimento armazenado, vá para o Gerenciador de Servidores e faça uma busca detalhada no NORTHWND.MDF banco de dados. (Se você não vir o Gerenciador de Servidores, abra-o indo para o menu Exibir e selecionando a opção Gerenciador de Servidores.)
No banco de dados, clique com o NORTHWND.MDF botão direito do mouse na pasta Stored Procedures, escolha Add New Stored Procedure e insira a seguinte sintaxe:
CREATE PROCEDURE dbo.GetProductsByCategory
(
@CategoryID int
)
AS
SELECT *
FROM Products
WHERE CategoryID = @CategoryID
Clique no ícone Salvar (ou Ctrl+S) para salvar o procedimento armazenado. Você pode testar o procedimento armazenado clicando com o botão direito do mouse nele na pasta Stored Procedures e escolhendo Executar. Isso solicitará os parâmetros do procedimento armazenado (@CategoryID, neste caso), após o qual os resultados serão exibidos na janela de Saída.
Figura 9: O GetProductsByCategory procedimento armazenado quando executado com um @CategoryID de 1 (Clique para visualizar a imagem em tamanho real)
Vamos usar este procedimento armazenado para exibir todos os produtos na categoria Bebidas em um GridView. Adicione um novo GridView à página e associe-o a um novo SqlDataSource chamado BeverageProductsDataSource. Continue para a tela Especificar uma instrução SQL personalizada ou procedimento armazenado, selecione o botão de opção Procedimento armazenado e escolha o GetProductsByCategory procedimento armazenado na lista suspensa.
Figura 10: Selecione o GetProductsByCategory procedimento armazenado na lista de Drop-Down (Clique para visualizar a imagem em tamanho real)
Como o procedimento armazenado aceita um parâmetro de entrada (@CategoryID), clicar em Avançar nos solicita que especifiquemos a origem para o valor desse parâmetro. As bebidas CategoryID são 1, portanto, deixe a lista suspensa Fonte do parâmetro em Nenhum e digite 1 na caixa de texto DefaultValue.
Figura 11: Use um valor de Hard-Coded de 1 para retornar os produtos na categoria de bebidas (Clique para visualizar a imagem em tamanho real)
Como mostra a marcação declarativa a seguir, ao usar um procedimento armazenado, a propriedade s SelectCommand de SqlDataSource é definida como o nome do procedimento armazenado e a SelectCommandType propriedade é definida como StoredProcedure, indicando que o é o SelectCommand nome de um procedimento armazenado em vez de uma instrução SQL ad-hoc.
<asp:SqlDataSource ID="BeverageProductsDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand="GetProductsByCategory" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter DefaultValue="1" Name="CategoryID" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
Teste a página em um navegador. Somente os produtos que pertencem à categoria Bebidas são exibidos, embora todos os campos do produto sejam exibidos, uma vez que o GetProductsByCategory procedimento armazenado retorna todas as colunas da Products tabela. Poderíamos, é claro, limitar ou personalizar os campos exibidos no GridView a partir da caixa de diálogo Editar colunas do GridView.
Figura 12: Todas as bebidas são exibidas (Clique para visualizar a imagem em tamanho real)
Etapa 4: Invocando programaticamente uma instrução Select() do SqlDataSource
Os exemplos que vimos no tutorial anterior e neste tutorial até agora vincularam controles SqlDataSource diretamente a um GridView. Os dados do controle SqlDataSource, no entanto, podem ser acessados programaticamente e enumerados no código. Isso pode ser particularmente útil quando você precisa consultar dados para inspecioná-los, mas não precisa exibi-los. Em vez de ter que escrever todo o código de ADO.NET clichê para se conectar ao banco de dados, especificar o comando e recuperar os resultados, você pode permitir que o SqlDataSource manipule esse código monótono.
Para ilustrar o trabalho com os dados do SqlDataSource programaticamente, imagine que seu chefe o abordou com uma solicitação para criar uma página da Web que exibe o nome de uma categoria selecionada aleatoriamente e seus produtos associados. Ou seja, quando um usuário visita esta página, queremos escolher aleatoriamente uma categoria da Categories tabela, exibir o nome da categoria e, em seguida, listar os produtos pertencentes a essa categoria.
Para conseguir isso, precisamos de dois controles SqlDataSource, um para pegar uma categoria aleatória da Categories tabela e outro para obter os produtos da categoria. Vamos criar o SqlDataSource que recupera um registro de categoria aleatório nesta etapa; A etapa 5 examina a criação do SqlDataSource que recupera os produtos da categoria.
Comece por adicionar um SqlDataSource a ParameterizedQueries.aspx e defina seu ID como RandomCategoryDataSource. Configure-o para que ele use a seguinte consulta SQL:
SELECT TOP 1 CategoryID, CategoryName
FROM Categories
ORDER BY NEWID()
ORDER BY NEWID() retorna os registros classificados em ordem aleatória (consulte Usando NEWID() para classificar registros aleatoriamente).
SELECT TOP 1 Devolve o primeiro registo do conjunto de resultados. Juntas, esta consulta retorna os valores da coluna CategoryID e CategoryName de uma única categoria selecionada aleatoriamente.
Para exibir o valor da categoria CategoryName, adicione um controle Web Label à página, defina a sua propriedade ID como CategoryNameLabel e limpe a sua propriedade Text. Para recuperar programaticamente os dados de um controle SqlDataSource, precisamos invocar seu Select() método. O Select() método espera um único parâmetro de entrada do tipo DataSourceSelectArguments, que especifica como os dados devem ser enviados antes de serem retornados. Isso pode incluir instruções sobre como classificar e filtrar os dados e é usado pelos controles da Web de dados ao classificar ou paginar os dados de um controle SqlDataSource. Para o nosso exemplo, porém, não precisamos que os dados sejam modificados antes de serem retornados e, portanto, passaremos no DataSourceSelectArguments.Empty objeto.
O Select() método retorna um objeto que implementa IEnumerable. O tipo preciso retornado depende do valor da propriedade s DataSourceModedo controle SqlDataSource. Conforme discutido no tutorial anterior, esta propriedade pode ser definida com um valor de DataSet ou DataReader. Se definido como DataSet, o Select() método retorna um objeto DataView ; se definido como DataReader, ele retorna um objeto que implementa IDataReader. Como o RandomCategoryDataSource SqlDataSource tem sua DataSourceMode propriedade definida como DataSet (o padrão), trabalharemos com um objeto DataView.
O código a seguir ilustra como recuperar os registos do RandomCategoryDataSource SqlDataSource como um DataView, bem como ler o CategoryName valor da coluna da primeira linha do DataView:
protected void Page_Load(object sender, EventArgs e)
{
// Get the data from the SqlDataSource as a DataView
DataView randomCategoryView =
(DataView)RandomCategoryDataSource.Select(DataSourceSelectArguments.Empty);
if (randomCategoryView.Count > 0)
{
// Assign the CategoryName value to the Label
CategoryNameLabel.Text =
string.Format("Here are Products in the {0} Category...",
randomCategoryView[0]["CategoryName"].ToString());
}
}
randomCategoryView[0] retorna o primeiro DataRowView no DataView.
randomCategoryView[0]["CategoryName"] retorna o valor da coluna CategoryName na primeira linha. Observe que o DataView é vagamente tipado. Para fazer referência a um determinado valor de coluna, precisamos passar o nome da coluna como uma cadeia de caracteres ( CategoryName, neste caso). A Figura 13 mostra a mensagem exibida no CategoryNameLabel ao visualizar a página. É claro que o nome real da categoria exibida é selecionado aleatoriamente pelo RandomCategoryDataSource SqlDataSource em cada visita à página (incluindo postbacks).
Figura 13: O nome da categoria selecionada aleatoriamente é exibido (Clique para visualizar a imagem em tamanho real)
Observação
Se a propriedade s DataSourceMode do controle SqlDataSource tivesse sido definida como DataReader, o valor de retorno do Select() método precisaria ser convertido para IDataReader. Para ler o valor da CategoryName coluna da primeira linha, usamos um código como:
if (randomCategoryReader.Read())
{
string categoryName = randomCategoryReader["CategoryName"].ToString();
...
}
Com o SqlDataSource selecionando aleatoriamente uma categoria, estamos prontos para adicionar o GridView que lista os produtos da categoria.
Observação
Em vez de usar um controle Web Label para exibir o nome da categoria, poderíamos ter adicionado um FormView ou DetailsView à página, vinculando-o ao SqlDataSource. O uso do Label, no entanto, nos permitiu explorar como invocar programaticamente a instrução SqlDataSource e Select() trabalhar com seus dados resultantes no código.
Etapa 5: Atribuindo valores de parâmetro programaticamente
Todos os exemplos que vimos até agora neste tutorial usaram um valor de parâmetro codificado ou um obtido de uma das fontes de parâmetro predefinidas (um valor querystring, um controle da Web na página e assim por diante). No entanto, os parâmetros do controle SqlDataSource também podem ser definidos programaticamente. Para concluir nosso exemplo atual, precisamos de um SqlDataSource que retorna todos os produtos pertencentes a uma categoria especificada. Este SqlDataSource terá um CategoryID parâmetro cujo valor precisa ser definido com base no valor da CategoryID coluna retornado pelo RandomCategoryDataSource SqlDataSource no manipulador de Page_Load eventos.
Comece adicionando um GridView à página e vincule-o a um novo SqlDataSource chamado ProductsByCategoryDataSource. Assim como fizemos na Etapa 3, configure o SqlDataSource para que ele invoque o GetProductsByCategory procedimento armazenado. Deixe a lista suspensa Origem do parâmetro definida como Nenhum, mas não insira um valor padrão, pois definiremos esse valor padrão programaticamente.
Figura 14: Não especifique uma fonte de parâmetro ou valor padrão (Clique para visualizar a imagem em tamanho real)
Depois de concluir o assistente SqlDataSource, a marcação declarativa resultante deve ser semelhante à seguinte:
<asp:SqlDataSource ID="ProductsByCategoryDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand="GetProductsByCategory" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter Name="CategoryID" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
Podemos atribuir programaticamente o DefaultValue do parâmetro CategoryID no manipulador de eventos Page_Load.
// Assign the ProductsByCategoryDataSource's
// CategoryID parameter's DefaultValue property
ProductsByCategoryDataSource.SelectParameters["CategoryID"].DefaultValue =
randomCategoryView[0]["CategoryID"].ToString();
Com essa adição, a página inclui um GridView que mostra os produtos associados à categoria selecionada aleatoriamente.
Figura 15: Não especifique uma fonte de parâmetro ou valor padrão (Clique para visualizar a imagem em tamanho real)
Resumo
O SqlDataSource permite que os desenvolvedores de página definam consultas parametrizadas cujos valores de parâmetro podem ser codificados, extraídos de fontes de parâmetros predefinidas ou atribuídos programaticamente. Neste tutorial, vimos como criar uma consulta parametrizada a partir do assistente Configurar Fonte de Dados para consultas SQL ad-hoc e procedimentos armazenados. Também analisamos o uso de fontes de parâmetros codificadas, um controle da Web como uma fonte de parâmetro e a especificação programática do valor do parâmetro.
Como com o ObjectDataSource, o SqlDataSource também fornece recursos para modificar seus dados subjacentes. No próximo tutorial, veremos como definir INSERT, UPDATEe DELETE instruções com o SqlDataSource. Depois que essas instruções forem adicionadas, podemos utilizar os recursos internos de inserção, edição e exclusão inerentes aos controles GridView, DetailsView e FormView.
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.
Um agradecimento especial a
Esta série de tutoriais foi revisada por muitos revisores úteis. Os principais revisores deste tutorial foram Scott Clyde, Randell Schmidt e Ken Pespisa. Interessado em rever meus próximos artigos do MSDN? Se for o caso, envie-me uma mensagem para mitchell@4GuysFromRolla.com.
@CategoryID de 1" />