In diesem Artikel wird ein DataGrid erstellt, das ein CheckBox-Steuerelement enthält. Mit diesem Steuerelement können Benutzer mehrere Spalten zum detaillierten Durchsuchen auswählen. Wenn es keine Möglichkeit gibt, diese Funktionalität für dynamisches SQL wiederherzustellen, muss die IN-Operation verwendet werden.
Am Ende des Artikels haben wir eine benutzerdefinierte SQL Server-Funktion (UDF) geschrieben, um eine Zeichenfolge in durch Trennzeichen getrennte Teilzeichenfolgen zu unterteilen. In diesem Artikel können wir sehen, wie nützlich eine solche UDF sein kann. Wir erstellen ein Webformular, in dem der Benutzer einige Datensätze im DataGrid auswählen kann, indem er ein Kontrollkästchen-Steuerelement auswählt. Die Details dieser überprüften Datensätze werden in einem anderen DataGrid im Formular angezeigt. Dieses Formular sieht wie im Bild unten aus.
Unten sehen Sie die ASPX-Datei, die wir zum Erstellen des Formulars verwendet haben. Hinweis: So verwenden Sie TemplateColumn- und Checkbox-Steuerelemente, um DataGrid-Spalten zu vergrößern. Wir verwenden auch die DataKeyField-Eigenschaft des DataGrid, um dem Objekt mitzuteilen, welches Feld im Datenbankdatensatz den Schlüsselbezeichner der ersten Zeile enthalten wird.
<form id="Form1" method="post" runat="server">
<asp:DataGrid id="DataGrid1" runat="server"
AutoGenerateColumns="False" DataKeyField="EmployeeID">
<Spalten>
<asp:TemplateColumn>
<ItemTemplate>
<asp:CheckBox runat="server" ID="EmployeeCheckBox" />
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn>
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "LastName") %>,
<%# DataBinder.Eval(Container.DataItem, "FirstName") %>
</ItemTemplate>
</asp:TemplateColumn>
</Spalten>
</asp:DataGrid>
<hr>
<asp:Button id="Bestellungen" runat="server" Text="Bestellungen anzeigen"></asp:Button>
<hr>
<asp:DataGrid ID="DataGrid2" Runat="server" AutoGenerateColumns="True" />
</form>
Wenn das Formular geladen und initialisiert wird, muss das obere DataGrid zusammengestellt werden. Der Code greift mithilfe der Enterprise-Bibliothek auf die SQL Server Northwind-Beispieldatenbank zu und führt die Anweisung „SELECT EmployeeID, FirstName, LastName FROM Employees“ aus. Der Code für das Ladeereignis lautet wie folgt:
private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{
Datenbank db = DatabaseFactory.CreateDatabase();
DBCommandWrapper dbCommandWrapper;
using(dbCommandWrapper = db.GetSqlStringCommandWrapper(SELECT_EMPLOYEES))
{
mit (IDataReader dataReader = db.ExecuteReader(dbCommandWrapper))
{
DataGrid1.DataSource = dataReader;
DataGrid1.DataBind();
}
}
}
}
Wenn der Benutzer auf die Schaltfläche „Bestellungen“ klickt, möchten wir eine zweite Datentabelle anzeigen, die mit denen in der Datenbank „Mitarbeiter“ übereinstimmt und sich auf die Daten „Bestellungen“ bezieht. Eine Möglichkeit hierfür besteht darin, dynamisches SQL zu erstellen und die ODER-Bedingung aller für die WHERE-Anweisung erforderlichen Mitarbeiter-IDs zu verwenden.
Die zweite Methode besteht darin, die IN-Operation der WHERE-Anweisung zu verwenden. Die IN-Operation vergleicht eine Liste von Ausdrücken. Die folgende Anweisung gibt beispielsweise Informationen zwischen den Mitarbeiter-IDS 7 und 4 zurück.
SELECT EmployeeID, FirstName, LastName FROM Employees WHERE EmployeeID IN (7, 4)
Konzeptionell würde ich gerne einen einzelnen String-Parameter verwenden, um die übergebenen IDs abzufragen, aber vielleicht als einzelner String kann er nicht für die IN-Operation A verwendet werden einzelner String-Parameter. In diesem Fall würde die SQL-Anweisung „WHERE Employee IN ('7, 4')“ lauten und die Datenbank würde eine Fehlermeldung zurückgeben, da EmployeeID vom Typ int und nicht vom Typ varchar ist.
Wir verwenden jedoch die im Artikel konstruierte Split-Funktion, um die Zeichenfolge in verschiedene Werte aufzuteilen. Übergeben Sie die Zeichenfolge „7, 4“ an die Split-Funktion und wir erhalten zwei Datensätze, die den Werten 4 und 7 entsprechen. Eine SQL-Abfrage zum Auswählen von Mitarbeitern und zum Zählen ihrer Bestellsummen würde wie folgt aussehen:
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
Um die obige Abfrage verwenden zu können, muss der Parameter @employeeIDs eingerichtet und übergeben werden. Dieser Parameter ist eine durch Kommas getrennte Liste von IDs. Um diese Zeichenfolge zu erstellen und herauszufinden, ob die Zeile vom Benutzer ausgewählt wurde, müssen wir eine Schleife verwenden, die die Anzahl der Zeilen durchläuft und jedes Kontrollkästchen-Steuerelement überprüft. Wenn der Benutzer eine Zeile auswählt, wird der Schlüssel in „Employee“ gespeichert, indem der Prüfer aus der DataKeys-Eigenschaft der Tabelle extrahiert wird (die in der ASPX-Datei erstellt wurde, um auf das Feld „EmployeeID“ zu verweisen).
privater String GetCheckedEmployeeIDs()
{
String-Trennzeichen = String.Empty;
StringBuilder EmployeeIDs = new StringBuilder();
for(int i = 0; i < DataGrid1.Items.Count; i++)
{
CheckBox-Kontrollkästchen;
checkbox = DataGrid1.Items[i].FindControl("EmployeeCheckBox") as CheckBox;
if(checkbox != null && checkbox.Checked == true)
{
EmployeeIDs.Append(delimiter + DataGrid1.DataKeys[i].ToString());
Trennzeichen = ",";
}
}
return EmployeeIDs.ToString();
}
Die obige Methode gibt einen String zurück, etwa „10, 7, 20“. Der Click-Event-Handler für die Schaltfläche „Bestellungen“ umfasst eine Methode, die Informationen an SQL übergibt, um eine Liste von Mitarbeitern und Bestellungen abzurufen, und die Ergebnisse in ein zweites DataGrid-Objekt bindet.
private void Orders_Click(object sender, System.EventArgs e)
{
string EmployeeIDs = GetCheckedEmployeeIDs();
Datenbank db = DatabaseFactory.CreateDatabase();
DBCommandWrapper dbCommandWrapper;
using(dbCommandWrapper = db.GetSqlStringCommandWrapper(SELECT_ORDERS))
{
dbCommandWrapper.AddInParameter("@employeeIDs", DbType.String, EmployeeIDs);
mit (IDataReader dataReader = db.ExecuteReader(dbCommandWrapper))
{
DataGrid2.DataSource = dataReader;
DataGrid2.DataBind();
}
}
}