Cet article créera un DataGrid contenant un contrôle CheckBox. Ce contrôle permet aux utilisateurs de sélectionner plusieurs colonnes pour une navigation détaillée. S'il n'existe aucun moyen de récupérer cette fonctionnalité pour le SQL dynamique, l'opération IN doit être utilisée.
À la fin de l'article, nous avons écrit une fonction définie par l'utilisateur (UDF) SQL Server afin de diviser une chaîne en sous-chaînes délimitées. Dans cet article, nous pouvons voir à quel point une telle UDF peut s’avérer utile. Nous allons créer un formulaire Web dans lequel l'utilisateur peut sélectionner certains enregistrements dans le DataGrid en sélectionnant une case à cocher. Les détails de ces enregistrements vérifiés apparaîtront dans un autre DataGrid du formulaire. Ce formulaire ressemble à l'image ci-dessous.
Vous trouverez ci-dessous l'ASPX que nous avons utilisé pour créer le formulaire. Remarque : Comment utiliser les contrôles TemplateColumn et Checkbox pour augmenter les colonnes DataGrid. Nous utilisons également la propriété DataKeyField de DataGrid pour indiquer à l'objet quel champ de l'enregistrement de la base de données contiendra l'identifiant de clé de la première ligne.
<form id="Form1" method="post" runat="server">
<asp:DataGrid id="DataGrid1" runat="serveur"
AutoGenerateColumns="False" DataKeyField="EmployeeID">
<Colonnes>
<asp:TemplateColumn>
<Modèle d'élément>
<asp:CheckBox runat="server" ID="EmployeeCheckBox" />
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn>
<Modèle d'élément>
<%# DataBinder.Eval(Container.DataItem, "LastName") %>,
<%# DataBinder.Eval(Container.DataItem, "FirstName") %>
</ItemTemplate>
</asp:TemplateColumn>
</Colonnes>
</asp:DataGrid>
<hr>
<asp:Button id="Commandes" runat="server" Text="Afficher les commandes"></asp:Button>
<hr>
<asp:DataGrid ID="DataGrid2" Runat="server" AutoGenerateColumns="True" />
</form>
Lorsque le formulaire est chargé et initialisé, le DataGrid supérieur doit être assemblé. Le code utilise la bibliothèque d'entreprise pour accéder à l'exemple de base de données SQL Server Northwind et exécute l'instruction « SELECT EmployeeID, FirstName, LastName FROM Employees ». Le code de l'événement de chargement est le suivant :
private void Page_Load (object sender, System.EventArgs e)
{
si(!Page.IsPostBack)
{
Base de données base de données = DatabaseFactory.CreateDatabase();
DBCommandWrapper dbCommandWrapper ;
utilisant (dbCommandWrapper = db.GetSqlStringCommandWrapper(SELECT_EMPLOYEES))
{
en utilisant (IDataReader dataReader = db.ExecuteReader(dbCommandWrapper))
{
DataGrid1.DataSource = dataReader ;
DataGrid1.DataBind();
}
}
}
}
Lorsque l'utilisateur clique sur le bouton "Commandes", nous souhaitons afficher un deuxième tableau de données qui correspond à ceux de la base de données avec les employés et est lié aux données des commandes. Une façon de procéder consiste à créer du SQL dynamique et à utiliser la condition OR de tous les EmployeeID requis pour l'instruction WHERE.
La deuxième méthode consiste à utiliser l'opération IN de l'instruction WHERE. L'opération IN compare une liste d'expressions. Par exemple, l'instruction suivante renvoie des informations entre les ID d'employé 7 et 4.
SELECT EmployeeID, FirstName, LastName FROM Employees WHERE EmployeeID IN (7, 4)
Conceptuellement, j'aimerais utiliser un seul paramètre de chaîne pour interroger les ID transmis. Cependant, peut-être en tant que chaîne unique, il ne peut pas être utilisé pour l'opération IN A. paramètre de chaîne unique. Dans ce cas, l'instruction SQL serait "WHERE Employee IN ('7, 4')" et la base de données renverrait un message d'erreur car EmployeeID est de type int - pas varchar.
Cependant, nous utilisons la fonction split construite dans l'article pour séparer la chaîne en différentes valeurs. Passez la chaîne '7, 4' à la fonction split et nous obtiendrons deux enregistrements correspondant aux valeurs 4 et 7. Une requête SQL pour sélectionner les employés et compter le total de leurs commandes serait la suivante :
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
Ce qui est nécessaire pour utiliser la requête ci-dessus est que le paramètre @employeeIDs doit être établi et transmis. Ce paramètre sera une liste d’identifiants séparés par des virgules. Pour construire cette chaîne, afin de savoir si la ligne a été sélectionnée par l'utilisateur, nous devons utiliser une boucle qui parcourt le nombre de lignes et vérifie chaque contrôle de case à cocher. Si l'utilisateur sélectionne une ligne, la clé est enregistrée dans Employee en extrayant l'examinateur de la propriété DataKeys de la table (qui a été créée dans le fichier ASPX pour pointer vers le champ EmployeeID).
chaîne privée GetCheckedEmployeeIDs()
{
Délimiteur de chaîne = String.Empty ;
StringBuilder EmployeeIDs = new StringBuilder();
pour (int i = 0; i < DataGrid1.Items.Count; i++)
{
Case à cocher CheckBox ;
checkbox = DataGrid1.Items[i].FindControl("EmployeeCheckBox") comme CheckBox ;
if(checkbox != null && checkbox.Checked == true)
{
employeIDs.Append(delimiter + DataGrid1.DataKeys[i].ToString());
délimiteur = ",";
}
}
return employeIDs.ToString();
}
La méthode ci-dessus renvoie une chaîne, comme "10, 7, 20". Le gestionnaire d'événements de clic sur le bouton Commandes impliquera une méthode qui transmet des informations à SQL pour obtenir une liste d'employés et de commandes, et lie les résultats dans un deuxième objet DataGrid.
private void Orders_Click (expéditeur d'objet, System.EventArgs e)
{
chaîne EmployeeIDs = GetCheckedEmployeeIDs();
Base de données base de données = DatabaseFactory.CreateDatabase();
DBCommandWrapper dbCommandWrapper ;
utilisant (dbCommandWrapper = db.GetSqlStringCommandWrapper(SELECT_ORDERS))
{
dbCommandWrapper.AddInParameter("@employeeIDs", DbType.String, EmployeeIDs);
en utilisant (IDataReader dataReader = db.ExecuteReader(dbCommandWrapper))
{
DataGrid2.DataSource = dataReader ;
DataGrid2.DataBind();
}
}
}