Este artigo criará um DataGrid contendo um controle CheckBox. Este controle permite aos usuários selecionar várias colunas para navegação detalhada. Se não houver como recuperar esta funcionalidade para SQL dinâmico, então a operação IN deverá ser utilizada.
No final do artigo, escrevemos uma função definida pelo usuário (UDF) do SQL Server para quebrar uma string em substrings delimitadas. Neste artigo, podemos ver como tal UDF pode ser útil. Criaremos um formulário web onde o usuário poderá selecionar alguns registros no DataGrid selecionando um controle checkbox. Os detalhes desses registros verificados aparecerão em outro DataGrid do formulário. Este formulário se parece com a imagem abaixo.
Abaixo é mostrado o ASPX que usamos para criar o formulário. Nota: Como usar os controles TemplateColumn e Checkbox para aumentar as colunas do DataGrid. Também usamos a propriedade DataKeyField do DataGrid para informar ao objeto qual campo no registro do banco de dados conterá o identificador de chave da primeira linha.
<form id="Form1" method="post" runat="servidor">
<asp:DataGrid id="DataGrid1" runat="servidor"
AutoGenerateColumns="False" DataKeyField="EmployeeID">
<Colunas>
<asp:TemplateColumn>
<ItemTemplate>
<asp:CheckBox runat="servidor" ID="EmployeeCheckBox" />
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn>
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "Sobrenome") %>,
<%# DataBinder.Eval(Container.DataItem, "Nome") %>
</ItemTemplate>
</asp:TemplateColumn>
</Colunas>
</asp:DataGrid>
<hr>
<asp:Button id="Pedidos" runat="servidor" Text="Ver pedidos"></asp:Button>
<h>
<asp:DataGrid ID="DataGrid2" Runat="servidor" AutoGenerateColumns="True" />
</form>
Quando o formulário é carregado e inicializado, o DataGrid superior precisa ser montado. O código usa a Biblioteca Corporativa para acessar o banco de dados de exemplo SQL Sever Northwind e executa a instrução "SELECT EmployeeID, FirstName, LastName FROM Employees". O código para o evento de carregamento é o seguinte:
private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{
Banco de dados banco de dados = DatabaseFactory.CreateDatabase();
DBCommandWrapper dbCommandWrapper
usando(dbCommandWrapper = db.GetSqlStringCommandWrapper(SELECT_EMPLOYEES))
{
usando (IDataReader dataReader = db.ExecuteReader(dbCommandWrapper))
{
DataGrid1.DataSource = leitor de dados;
DataGrid1.DataBind();
}
}
}
}
Quando o usuário clica no botão "Pedidos", queremos exibir uma segunda tabela de dados que corresponda aos dados do banco de dados com Funcionários e esteja relacionada aos dados dos Pedidos. Uma maneira de fazer isso é criar SQL dinâmico e usar a condição OR de todos os EmployeeIDs necessários para a instrução WHERE.
O segundo método é usar a operação IN da instrução WHERE. A operação IN compara uma lista de expressões. Por exemplo, a instrução a seguir retorna informações entre os IDS 7 e 4 do funcionário.
SELECT EmployeeID, FirstName, LastName FROM Employees WHERE EmployeeID IN (7, 4)
Conceitualmente, eu gostaria de usar um único parâmetro de string para consultar os IDs passados, porém, talvez como uma única string, ele não pode ser usado para a operação IN A parâmetro de string única. Nesse caso, a instrução SQL seria "WHERE Employee IN ('7, 4')" e o banco de dados retornaria uma mensagem de erro porque EmployeeID é do tipo int - não varchar.
No entanto, usamos a função split construída no artigo para separar a string em valores diferentes. Passe a string '7, 4' para a função split e obteremos dois registros correspondentes aos valores 4 e 7. Uma consulta SQL para selecionar funcionários e contar o total de seus pedidos seria a seguinte:
SELECT count(*) AS Orders, E.FirstName, E.LastName
FROM Orders O
INNER JOIN Employees E ON O.EmployeeID = E.EmployeeID
WHERE E.EmployeeID IN(SELECT Value FROM fn_Split(@employeeIDs, ','))
GROUP BY FirstName, LastName
ORDER BY count(*) DESC
O que é necessário para usar a consulta acima é que o parâmetro @employeeIDs deve ser estabelecido e passado. Este parâmetro será uma lista de IDs separados por vírgulas. Para construir essa string, para descobrir se a linha foi selecionada pelo usuário, precisamos usar um loop que itera pelo número de linhas e verifica cada controle de caixa de seleção. Caso o usuário selecione uma linha, a chave é salva em funcionário extraindo o examinador da propriedade DataKeys da tabela (que foi criada no arquivo ASPX para apontar para o campo EmployeeID).
string privada GetCheckedEmployeeIDs()
{
Delimitador de string = String.Empty;
StringBuilder EmployeeIDs = new StringBuilder();
for(int i = 0; i < DataGrid1.Items.Count; i++)
{
Caixa de seleção CheckBox;
checkbox = DataGrid1.Items[i].FindControl("EmployeeCheckBox") as CheckBox;
if (caixa de seleção! = null && caixa de seleção. Verificado == verdadeiro)
{
EmployeeIDs.Append(delimitador + DataGrid1.DataKeys[i].ToString());
delimitador = ",";
}
}
return EmployeeIDs.ToString();
}
O método acima retorna uma string, como "10, 7, 20". O manipulador de eventos de clique do botão Pedidos envolverá um método que passa informações ao SQL para obter uma lista de funcionários e pedidos e vincula os resultados em um segundo objeto DataGrid.
private void Orders_Click (objeto remetente, System.EventArgs e)
{
string EmployeeIDs = GetCheckedEmployeeIDs();
Banco de dados banco de dados = DatabaseFactory.CreateDatabase();
DBCommandWrapper dbCommandWrapper
usando(dbCommandWrapper = db.GetSqlStringCommandWrapper(SELECT_ORDERS))
{
dbCommandWrapper.AddInParameter("@employeeIDs", DbType.String, EmployeeIDs);
usando (IDataReader dataReader = db.ExecuteReader(dbCommandWrapper))
{
DataGrid2.DataSource = leitor de dados;
DataGrid2.DataBind();
}
}
}