Für die Darstellung einer Produkthitliste samt Paging habe ich neben dem Recordset für die Produkte auch noch die gesamte Anzahl der Records benötigt.
Da die Abfragen (Volltextsuche...) doch sehr komplex sind, hat es sich als wenig performant erwiesen jeweils eine Abfrage für das Recordset und eine für den Count(*) zu machen - war ja klar ;-)
Die Lösung: eine Stored Procedure mit Output-Parameter. Diese gibt nun nicht nur das Recordset wieder, sondern zusätzlich noch die Anzahl der gefundenen Datensätze.
Die einfache Lösung schaut wie folgt aus:
SqlConnection oConn
= new SqlConnection(ConfigurationSettings.AppSettings["ConnString"]);
oConn
.Open();
SqlCommand cmd
= new SqlCommand("sproc_getProductHitlistVolltext_Output", oConn);
cmd
.CommandType = CommandType.StoredProcedure;
SqlParameter param
= cmd.Parameters.Add("@rowsAnz", SqlDbType.Int);
param
.Direction = ParameterDirection.Output;
param
= cmd.Parameters.Add("@volltext", SqlDbType.VarChar);
param
.Value = "mb vaneo";
cmd
.ExecuteNonQuery();
Response
.Write(cmd.Parameters["@rowsAnz"].Value);
oConn
.Close();
Hier gebe ich mir am Ende nur den Count Zurück, via cmd.ExecuteReader könnte man nun aber zum Beispiel auch mit dem DataReader die Records durchlaufen.
Allerdings war das Problem etwas komplexer, denn die Hitlist selbst wurde mit einem Repeater realisiert - und der braucht in diesem Fall als DataSource ein DataSet, was wiederum durch einen DataAdapter befüllt werden muss. Aber wie kriege ich nun all die Daten in den DataAdapter? So:
SqlCommand cmd
= new SqlCommand();
SqlParameter param = new SqlParameter();
cmd.CommandText = "sproc_getProductHitlistVolltext_Output";
cmd.Connection = oConn;
cmd.CommandType = CommandType.StoredProcedure;
param
= cmd.Parameters.Add("@volltext", SqlDbType.VarChar);
param.Value = "mb vaneo";
param
= cmd.Parameters.Add("@rowsAnz", SqlDbType.Int);
param.Direction = ParameterDirection.Output;
// DataAdapter erstellen
SqlDataAdapter da = new SqlDataAdapter(cmd);
// DataSet erstellen
DataSet ds = new DataSet();
// Startrecord bestimmen
startRecord = (CurrentPage-1)*PageSize;
// Datensätze holen
da.Fill(ds,startRecord,PageSize,"Products");
// TotalSize
TotalSize = int.Parse(cmd.Parameters["@rowsAnz"].Value.ToString());
// Repeater mit Datensätzen füllen, bzw. binden
RHitlist.DataSource = ds.Tables["Products"].DefaultView;
RHitlist.DataBind();
That's it! Die Procedure selbst sieht übrigens in etwa so aus:
ALTER PROCEDURE
dbo.sproc_getProductHitlistVolltext_Output (
@volltext varchar(255),
@rowsAnz int output
)
AS
Select ...
Set
@rowsAnz =@@ROWCOUNT