Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
por Scott Mitchell
Neste tutorial, continuamos nossa análise do controle SqlDataSource e aprendemos a definir consultas parametrizadas. Os parâmetros podem ser especificados de forma declarativa e programática e podem ser extraídos de vários locais, como o querystring, o 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 use um procedimento armazenado. Seja selecionando colunas de uma tabela ou visão, ou inserindo uma instrução SQL personalizada, a propriedade do controle SqlDataSource SelectCommand recebe a instrução SQL ad hoc SELECT resultante, e é essa SELECT instrução que é executada quando o método SqlDataSource Select() é invocado (seja programaticamente ou automaticamente a partir de um controle de dados da Web).
As instruções SQL SELECT usadas nas demonstrações do tutorial anterior não tinham WHERE cláusulas. Em uma SELECT instruçã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, poderíamos 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 Web na página. O ideal é que essas entradas sejam especificadas por meio 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 dá suporte a consultas parametrizadas tanto para instruções SELECT quanto para instruções INSERT, UPDATE e DELETE. Além disso, os valores de parâmetro podem ser extraídos automaticamente de uma variedade de fontes, como o querystring, o estado da sessão, ou os controles na página e assim por diante, ou podem ser atribuídos programaticamente. Neste tutorial, veremos como definir consultas parametrizadas, bem como como especificar os valores de parâmetro de forma declarativa e programática.
Observação
No tutorial anterior, comparamos o ObjectDataSource que foi nossa ferramenta de escolha nos primeiros 46 tutoriais com o SqlDataSource, observando suas semelhanças conceituais. Essas semelhanças também se estendem a parâmetros. Os parâmetros do ObjectDataSource são mapeados para os parâmetros de entrada dos métodos na Camada Lógica de Negócios. Com o SqlDataSource, os parâmetros são definidos diretamente na consulta SQL. Ambos os controles têm coleções de parâmetros para seus Select()Insert()Update()métodos, e Delete() ambos podem ter esses valores de parâmetro preenchidos de fontes predefinidas (valores de querystring, variáveis de sessão e assim por diante) ou atribuídos programaticamente.
Criando uma consulta parametrizada
O assistente de configuração da fonte de dados do controle SqlDataSource oferece três opções para especificar o comando a ser executado para recuperar registros de banco de dados.
- Escolhendo as colunas de uma tabela ou exibição existente,
- Inserindo uma instrução SQL personalizada ou
- Ao escolher um procedimento armazenado
Ao escolher colunas de uma tabela ou exibição existente, os parâmetros da 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 indicar 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 os SqlDataSource s SelectCommand são especificados, vamos dar uma olhada nas três abordagens. Para começar, abra a ParameterizedQueries.aspx página na pasta SqlDataSource, arraste um controle SqlDataSource da Caixa de Ferramentas para o Designer, e defina seu ID para Products25BucksAndUnderDataSource. Em seguida, clique no link Configurar Fonte de Dados do elemento inteligente do controle. Selecione o banco de dados a ser usado (NORTHWINDConnectionString) e clique em Avançar.
Etapa 1: Adicionar 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 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: escolher as colunas a serem retornadas de uma tabela ou exibição (clique para exibir a imagem em tamanho real)
Para incluir uma WHERE cláusula na SELECT instrução, clique no WHERE botão, que abre a caixa de diálogo Adicionar WHERE Cláusula (consulte a Figura 2). Para adicionar um parâmetro para limitar os resultados retornados pela SELECT consulta, primeiro escolha a coluna para 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, como da string de consulta ou do estado de 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 US$ 25,00. Portanto, selecione UnitPrice na lista suspensa de Colunas e <= na lista suspensa de Operadores. Ao usar um valor de parâmetro codificado (como US$ 25,00) ou se o valor do parâmetro deve ser especificado programaticamente, selecione Nenhum na lista suspensa Origem. Em seguida, insira o valor do parâmetro codificado em código 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 Adicionar WHERE Cláusula (Clique para exibir 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 você especificar várias condições na cláusula WHERE da caixa de diálogo Adicionar Cláusula WHERE, o assistente as unirá com o operador AND. Se você precisar incluir um OR na cláusula WHERE (como WHERE UnitPrice <= @UnitPrice OR Discontinued = 1), então precisará construir a instrução SELECT na tela de instruções SQL personalizadas.
Conclua a configuração do SqlDataSource (clique em Avançar, depois Concluir) e inspecione a marcação declarativa do SqlDataSource. A marcação agora inclui uma <SelectParameters> coleção, que explica as fontes dos 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 Select() sqlDataSource é invocado, o valor do parâmetro UnitPrice (25,00) é aplicado ao parâmetro @UnitPrice no SelectCommand antes de ser enviado para o banco de dados. O resultado líquido é que apenas os produtos menores ou iguais a US$ 25,00 são retornados da Products tabela. Para confirmar isso, adicione um GridView à página, associe-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 US$ 25,00, como confirma a Figura 3.
Figura 3: Somente os produtos menores ou iguais a US$ 25,00 são exibidos (clique para exibir a imagem em tamanho real)
Etapa 2: Adicionar 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 Filter do Construtor de Consultas. Para demonstrar isso, vamos exibir apenas esses produtos em um GridView cujos preços são menores que um determinado limite. Comece adicionando um TextBox à ParameterizedQueries.aspx página para coletar esse valor de limite do usuário. Defina a propriedade IDtextBox como MaxPrice . Adicione um controle Web de botão e defina sua Text propriedade como Exibir Produtos Correspondentes.
Em seguida, arraste um GridView para a página e, da sua marca inteligente, selecione a opção de 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 por meio 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 exibir a imagem em tamanho real)
Como a consulta inclui parâmetros, a próxima tela do assistente nos solicita a origem dos valores de parâmetros. Escolha Controle na lista suspensa de origem do parâmetro e MaxPrice (valor do controle TextBox ID) na lista suspensa ControlID. Você também pode inserir um valor padrão opcional a ser usado no caso em que o usuário não inseriu nenhum texto no MaxPrice TextBox. Por enquanto, não insira um valor padrão.
Figura 5: A MaxPrice propriedade TextBox s Text é usada como a origem do parâmetro (clique para exibir a imagem em tamanho real)
Conclua o assistente Configurar Fonte de Dados clicando em Avançar e depois 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 na seção SqlDataSource é um <SelectParameters>, que é um ControlParameter, que inclui propriedades adicionais como ControlID e PropertyName. Quando o método SqlDataSource Select() é invocado, o ControlParameter extrai o valor da propriedade especificada do controle da Web 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 exibir esta página por meio de um navegador. Ao visitar pela primeira vez a página ou sempre que a MaxPrice Caixa de Texto não tiver um valor, nenhum registro será exibido no GridView.
Figura 6: Nenhum registro é exibido quando a MaxPrice Caixa de Texto está vazia (clique para exibir a imagem em tamanho real)
O motivo pelo 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 ao GridView que uma de suas fontes de parâmetro foi alterada. Consequentemente, o GridView se vincula novamente ao SqlDataSource, exibindo esses produtos menores ou iguais a US$ 5,00.
Figura 7: Produtos menores ou iguais a US$ 5,00 são exibidos (clique para exibir imagem em tamanho real)
Inicialmente exibindo todos os produtos
Em vez de não exibir nenhum produto quando a página for carregada pela primeira vez, talvez queiramos exibir todos os produtos. Uma maneira de listar todos os produtos sempre que o MaxPrice TextBox estiver vazio é definir o valor padrão do parâmetro como um valor insanamente alto, como 1000000, já que é improvável que a Northwind Traders tenha estoque cujo preço unitário exceda US$ 1.000.000. No entanto, essa abordagem é míope e pode não funcionar em outras situações.
Em tutoriais anteriores - Parâmetros Declarativos e Filtragem Mestre/Detalhes com um DropDownList , enfrentamos um problema semelhante. Nossa solução era colocar essa lógica na Camada Lógica de Negócios. Especificamente, a BLL examinou o valor de entrada e, se fosse NULL ou algum valor reservado, a chamada foi roteada para o método DAL que retornou todos os registros. Se o valor de entrada fosse um valor de filtragem normal, uma chamada foi feita para o método DAL que executou 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 selecionar de forma inteligente todos os registros se o parâmetro @MaximumPrice for NULL ou algum valor reservado. Para este exercício, vamos configurar de forma que, se o parâmetro @MaximumPrice for igual a -1.0, todos os registros sejam retornados. (-1.0 atua como um valor reservado, pois nenhum produto pode ter um valor UnitPrice negativo.) Para fazer isso, podemos usar a seguinte instrução SQL:
SELECT ProductName, UnitPrice
FROM Products
WHERE UnitPrice <= @MaximumPrice OR @MaximumPrice = -1.0
Essa WHERE cláusula retorna todos os registros se o parâmetro @MaximumPrice é igual a -1.0. Se o valor do parâmetro não for -1.0, somente os produtos cujo valor de UnitPrice é menor ou igual ao valor do parâmetro @MaximumPrice serão retornados. Ao definir o valor padrão do parâmetro @MaximumPrice como -1.0, na primeira carga de 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 MaxPrice Caixa de Texto está Vazia (Clique para exibir a imagem em tamanho real)
Há algumas ressalvas a serem observadas com essa abordagem. Primeiro, perceba que o tipo de dados do parâmetro é inferido pelo uso na consulta SQL. Se você alterar a WHERE cláusula de @MaximumPrice = -1.0 para @MaximumPrice = -1, o runtime tratará o parâmetro como um inteiro. Se 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 WHERE cláusula ou, melhor ainda, defina a ControlParameter propriedade do Type objeto como Decimal.
Em segundo lugar, ao adicionar OR @MaximumPrice = -1.0 à cláusula WHERE, o mecanismo de consulta não pode usar um índice em UnitPrice (supondo que exista), resultando assim em uma varredura de tabela. Isso poderá afetar o desempenho se houver um número suficientemente grande de registros na Products tabela. Uma abordagem melhor seria mover essa lógica para um procedimento armazenado em que uma instrução IF 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 nas instruções SQL definidas 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 nomeado @CategoryID e retorna todas as colunas dos produtos cuja CategoryID coluna corresponde @CategoryID. Para criar um procedimento armazenado, acesse 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 acessando o menu Exibir e selecionando a opção Gerenciador de Servidores.)
NORTHWND.MDF No banco de dados, clique com o botão direito do mouse na pasta Procedimentos Armazenados, escolha Adicionar Novo Procedimento Armazenado 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 na pasta Procedimentos Armazenados e escolhendo Executar. Isso solicitará os parâmetros do procedimento armazenado (@CategoryID nesta instância), após o que 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 exibir a imagem em tamanho real)
Vamos usar esse 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 um procedimento armazenado, selecione o botão de rádio Procedimento armazenado e escolha o procedimento armazenado GetProductsByCategory na lista suspensa.
Figura 10: Selecione o GetProductsByCategory Procedimento Armazenado na Lista de Drop-Down (Clique para exibir a imagem em tamanho real)
Como o procedimento armazenado aceita um parâmetro de entrada (@CategoryID), clicar em Avançar solicita que especifique a origem desse valor de parâmetro. O parâmetro Bebidas CategoryID é 1, então deixe a lista suspensa de origem do parâmetro em Nenhum e insira 1 na caixa de texto DefaultValue.
Figura 11: Usar um valor de Hard-Coded de 1 para retornar os produtos na categoria bebidas (clique para exibir a imagem em tamanho real)
Como mostra a marcação declarativa a seguir, ao usar um procedimento armazenado, a propriedade sqlDataSource SelectCommand é definida como o nome do procedimento armazenado e a SelectCommandType propriedade é definida como StoredProcedure, indicando que 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, pois o GetProductsByCategory procedimento armazenado retorna todas as colunas da Products tabela. É claro que poderíamos limitar ou personalizar os campos exibidos no GridView na caixa de diálogo Editar Colunas do GridView.
Figura 12: Todas as bebidas são exibidas (clique para exibir 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 associaram controles SqlDataSource diretamente a um GridView. Os dados do controle SqlDataSource, no entanto, podem ser acessados e enumerados programaticamente 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 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 como trabalhar com os dados do SqlDataSource de forma programática, imagine que seu chefe tenha se aproximado de você 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 essa página, queremos escolher aleatoriamente uma categoria na Categories tabela, exibir o nome da categoria e, em seguida, listar os produtos que pertencem a essa categoria.
Para fazer isso, precisamos de dois controles SqlDataSource um para obter uma categoria aleatória da Categories tabela e outra para obter os produtos da categoria. Criaremos o SqlDataSource que recupera um registro de categoria aleatório nesta etapa; A etapa 5 analisa a criação do SqlDataSource que recupera os produtos da categoria.
Comece adicionando um SqlDataSource a ParameterizedQueries.aspx e defina sua ID para 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 Using NEWID() to Randomly Sort Records).
SELECT TOP 1 retorna o primeiro registro do conjunto de resultados. Juntas, essa consulta retorna os valores das colunas CategoryID e CategoryName de uma única categoria selecionada aleatoriamente.
Para exibir o valor da categoria CategoryName, adicione um controle Web label à página, defina sua propriedade ID como CategoryNameLabel e limpe 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 recebidos 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 nosso exemplo, porém, não precisamos que os dados sejam modificados antes de serem retornados e, portanto, passaremos o DataSourceSelectArguments.Empty objeto.
O Select() método retorna um objeto que implementa IEnumerable. O tipo preciso retornado depende do valor da propriedade DataSourceMode do controle SqlDataSource. Conforme discutido no tutorial anterior, essa propriedade pode ser definida como um valor igual DataSet ou DataReader. Se definido como DataSet, o Select() método retornará um objeto DataView ; se definido como DataReader, ele retornará um objeto que implementa IDataReader. Como o RandomCategoryDataSource SqlDataSource tem sua DataSourceMode propriedade definida DataSet como (o padrão), trabalharemos com um objeto DataView.
O código a seguir ilustra como recuperar os registros do RandomCategoryDataSource SqlDataSource como um DataView, bem como como ler o CategoryName valor da coluna da primeira linha 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 CategoryName coluna nesta primeira linha. Observe que o DataView é vagamente tipado. Para fazer referência a um valor de coluna específico, precisamos passar o nome da coluna como uma cadeia de caracteres (CategoryName, nesse caso). A Figura 13 mostra a mensagem exibida na CategoryNameLabel quando se visualiza a página. Claro, o nome real da categoria exibido é selecionado de forma aleatória pelo RandomCategoryDataSource SqlDataSource a cada visita à página (incluindo postbacks).
Figura 13: o nome da categoria selecionada aleatoriamente é exibido (clique para exibir a imagem em tamanho real)
Observação
Se a propriedade do controle SqlDataSource DataSourceMode tivesse sido definida como DataReader, o valor retornado do método Select() precisaria ser convertido em IDataReader. Para ler o valor da coluna CategoryName da primeira linha, usaríamos 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 de rótulo para exibir o nome da categoria, poderíamos ter adicionado um FormView ou DetailsView à página, associando-o ao SqlDataSource. No entanto, o uso do Rótulo nos permitiu explorar como invocar programaticamente a instrução sqlDataSource Select() e trabalhar com seus dados resultantes no código.
Etapa 5: Atribuindo valores de parâmetro de forma programática
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 de querystring, um controle 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 retorne todos os produtos pertencentes a uma categoria especificada. Esse SqlDataSource terá um CategoryID parâmetro cujo valor precisa ser definido com base no valor da CategoryID coluna retornado pelo RandomCategoryDataSource SqlDataSource no Page_Load manipulador de eventos.
Comece adicionando um GridView à página e associe-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 de origem de 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 origem de parâmetro ou valor padrão (clique para exibir 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 DefaultValue do parâmetro CategoryID programaticamente 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 origem de parâmetro ou valor padrão (clique para exibir 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 em código, extraídos de fontes de parâmetro predefinidas ou atribuídos programaticamente. Neste tutorial, vimos como criar uma consulta parametrizada do assistente Configurar Fonte de Dados para consultas SQL ad hoc e procedimentos armazenados. Também examinamos o uso de fontes de parâmetros fixas, um controle da web como uma fonte de parâmetro, e especificamos programaticamente o valor do parâmetro.
Assim como com o ObjectDataSource, o SqlDataSource também fornece recursos para modificar seus dados subjacentes. No próximo tutorial, veremos como definir INSERTe UPDATEDELETE instruções com o SqlDataSource. Depois que essas instruções tiverem sido adicionadas, podemos utilizar os recursos internos de inserção, edição e exclusão inerentes aos controles GridView, DetailsView e FormView.
Divirta-se programando!
Sobre o autor
Scott Mitchell, autor de sete livros asp/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias da Microsoft Web desde 1998. Scott trabalha como consultor independente, treinador e escritor. Seu último livro é Sams Teach Yourself ASP.NET 2.0 em 24 Horas. Ele pode ser alcançado em mitchell@4GuysFromRolla.com.
Agradecimentos Especiais 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 revisar meus próximos artigos do MSDN? Se assim for, deixe-me uma linha em mitchell@4GuysFromRolla.com.
@CategoryID de 1" />