Verhalten eines ADO.Recordsets nachbilden

07/02/2008 - 18:05 von Uwe Ricken | Report spam
Guten Abend liebe Gemeinde,

die ersten Schritte mit .NET sind gemacht und es ist eigenlich auch nicht so
schwer. Trotzdem gelange ich jetzt erst einmal nicht mehr weiter bei der
folgenden Anforderung:

In meiner aktuellen Anwendung habe ich das Folgende programmiert:
Mittels einer Klasse (VBA) werden beim Start meiner Anwendung (ACCESS)
persistente Daten in ein "Disconnected RecordSet" geladen.

Dieses ADO-RecordSet hat die schöne Besonderheit, dass es...
- keine Verbindung mehr zur Datenbank hat
- die Daten beim Client im Speicher liegen
- sehr schnell abgerufen werden können.

Das gleiche möchte ich nun mit vb.net realisieren.
Der Hintergrund ist der Folgende:

- schnelle Verarbeitung auf dem Client
- wenig Traffic zum SQL-Server

Also habe ich mir eigentlich gedacht, dass ich alle Daten in einem
DataReader speichere.
Ich habe gelesen, dass ADO.NET grundsàtzlich die Verbindung zur Datenbank
wieder schließt, sobald die Daten ermittelt wurden.
Tja, das Problem, das ich jetzt aber habe...
- in einem DataReader kann ich nur vorwàrts gehen
- ich kann einen DataReader nicht filtern
- ich kann in einem DataReader nicht suchen

Mit einem ADO-Recordset konnte ich
- suchen (.FindFirst strCondition)
- filtern !!! (.Filter = strCondition; .FilterOn)

Gerade das Filtern war für mich Gold wert, weil ich die komplette
Konfiguration von Formularen (Aussehen und Verhalten der Controls) in der
Datenbank hinterlegt habe.

Zur Veranschaulichung habe ich hier mal meine .NET-Klasse, wie sie aktuell
programmiert ist.
Das Problem - jeder Request erzeugt einen Connect zur Datenbank und
anschließend die Rücklieferung des Ergebnisses. Ich hàtte aber eigentlich
gerne, dass genau diese ganze Geschichte beim Client ablàuft.

- Beim Start der Anwendung alle statischen Daten laden
- Verbindung zur Datenbank kappen
- Anforderung der statischen Daten (SQL-Statements, Messages, Settings) aus
dem lokalen Recordset lesen.

Aber das funnktioniert halt eben nicht.
Bitte nicht über die Art der Programmierung herziehen - ich bin noch sehr
start VB(A)-infiziert ;-)

Vielen herzlichen Dank für Eure Hilfe

Public Class SQL
Private cnn As New SqlClient.SqlConnection
Private cmd As New SqlClient.SqlCommand
Private prm As New SqlClient.SqlParameter

Private Const SQL_GET_SQLSTRING As String = "SELECT
dbo.fn_app_GetSQLString(@SQLFlag)"
Private Const SQL_SET_SQLSTRING As String =
"dbo.proc_app_WriteSQLString"

Private strSQLString As String

Public Sub New()
' Beim Initialisieren der Klasse wird eine Verbindung zum
' SQL-Server aufgebaut
cnn = New SqlClient.SqlConnection

With cnn
.ConnectionString = CNN_CONNECTIONSTRING
.Open()
End With
End Sub

Public Property SQLFlag() As String
Get
SQLFlag = strSQLString
End Get

Set(ByVal SQLFlag As String)
strSQLString = SQLFlag
End Set
End Property

Public Function GetSQLString() As String
Try
cmd = New SqlClient.SqlCommand
With cmd
.Connection = cnn
.CommandType = CommandType.Text
.CommandText = SQL_GET_SQLSTRING

prm = .Parameters.Add("@SQLFlag", SqlDbType.VarChar)

With prm
.Direction = ParameterDirection.Input
.Size = Len(SQLFlag) + 1
.Value = SQLFlag
End With

GetSQLString = .ExecuteScalar().ToString
End With
Catch ex As Exception
MsgBox(ex.Message.ToString)
GetSQLString = vbNullString
End Try
End Function

Public Function WriteSQLString(ByVal SQLText As String, ByVal
SQLDescription As String, ByVal IsSystem As Boolean) As Boolean
Dim ReturnValue As Long
Try
cmd = New SqlClient.SqlCommand
With cmd
.Connection = cnn
.CommandType = CommandType.StoredProcedure
.CommandText = SQL_SET_SQLSTRING

' Rückgabeparameter für die Auswertung
prm = .Parameters.Add("@ReturnValue", SqlDbType.Int)
prm.Direction = ParameterDirection.ReturnValue

' Erster Parameter ist der SQLFlag nach dem gesucht wird
prm = .Parameters.Add("@SQLFlag", SqlDbType.VarChar)
With prm
.Direction = ParameterDirection.Input
.Size = Len(SQLFlag) + 1
.Value = SQLFlag
End With

' Zweiter Parameter ist das neue SQL-Statement
prm = .Parameters.Add("@SQLText", SqlDbType.VarChar)
With prm
.Direction = ParameterDirection.Input
.Size = Len(SQLText) + 1
.Value = SQLText
End With

' Dritter Parameter ist die Beschreibung für das neue
SQLStatement
prm = .Parameters.Add("@SQLDescription", SqlDbType.VarChar)
With prm
.Direction = ParameterDirection.Input
.Size = Len(SQLDescription) + 1
.Value = SQLDescription
End With

' Vierter Parameter für die Definition, ob Systemflag
prm = .Parameters.Add("@SQLSystem", SqlDbType.Bit)
With prm
.Direction = ParameterDirection.Input
.Value = IsSystem
End With

.ExecuteNonQuery()
ReturnValue = CLng(.Parameters("@ReturnValue").Value)
If ReturnValue = 0 Then
WriteSQLString = False
Else
WriteSQLString = True
End If
End With
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Function

Protected Overrides Sub Finalize()
MyBase.Finalize()
Try
prm = Nothing
cmd = Nothing
cnn.Close()
cnn = Nothing
Catch ex As Exception
Debug.Print(ex.Message.ToString)
End Try
End Sub
End Class


Gruß, Uwe Ricken
MCP for SQL Server 2000 Database Implementation

db-Berater GmbH - 64390 Erzhausen
http://www.db-berater.de
http://www.memberadmin.de
http://www.conferenceadmin.de
____________________________________________________
dbdev: http://www.dbdev.org
FAQ: http://www.donkarl.com/AccessFAQ.htm
 

Lesen sie die antworten

#1 Stefan Falz [MVP]
07/02/2008 - 18:23 | Warnen spam
Hallo Uwe,

"Uwe Ricken" schrieb:

In meiner aktuellen Anwendung habe ich das Folgende programmiert:
Mittels einer Klasse (VBA) werden beim Start meiner Anwendung (ACCESS) persistente Daten in ein "Disconnected RecordSet" geladen.

Dieses ADO-RecordSet hat die schöne Besonderheit, dass es...
- keine Verbindung mehr zur Datenbank hat
- die Daten beim Client im Speicher liegen
- sehr schnell abgerufen werden können.



IMHO kàme dem eine DataTable, bzw. eine DataView am nàchsten. Damit lassen
sich dann auch Filter setzen, Sortierungen durchführen, ...

Also habe ich mir eigentlich gedacht, dass ich alle Daten in einem DataReader speichere.



Schlechte Idee (IMO)

Dim MyDataTable As New DataTable( ... )
Dim MyDataAdapter As New SqlDataAdapter( ... )
MyDataAdapter.Fill( MyDataTable )

Mittels MyDataTable.DefaultView kannst Du dann auf die DataView der
Table zugreifen.

Ich habe gelesen, dass ADO.NET grundsàtzlich die Verbindung zur Datenbank wieder schließt, sobald die Daten ermittelt wurden.



Nö. Nur wenn Du das so angibst.

Tschau, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

Ähnliche fragen