Konfigurowanie ustawień na poziomie połączenia i poleceń warstwy dostępu do danych (VB)
Klasy TableAdapters w zestawie danych typu automatycznie zajmują się nawiązywaniem połączenia z bazą danych, wydawaniem poleceń i wypełnianiem tabeli DataTable z wynikami. Istnieją jednak sytuacje, w których chcemy samodzielnie dbać o te szczegóły, a w tym samouczku dowiesz się, jak uzyskać dostęp do ustawień połączenia z bazą danych i na poziomie poleceń w tableAdapter.
Wprowadzenie
W ramach serii samouczków użyliśmy typów zestawów danych, aby zaimplementować warstwę dostępu do danych i obiekty biznesowe naszej architektury warstwowej. Zgodnie z opisem w pierwszym samouczku tabele danych typu DataTable służą jako repozytoria danych, podczas gdy klasy TableAdapters działają jako otoki do komunikowania się z bazą danych w celu pobrania i zmodyfikowania danych bazowych. Klasy TableAdapters hermetyzują złożoność związaną z pracą z bazą danych i zapisuje nam konieczność pisania kodu w celu nawiązania połączenia z bazą danych, wydawania polecenia lub wypełniania wyników w tabeli DataTable.
Czasami jednak musimy zakopać się w głębi tabeli TableAdapter i pisać kod, który działa bezpośrednio z obiektami ADO.NET. Na przykład w samouczku opakowującym modyfikacje bazy danych w ramach transakcji dodaliśmy metody do klasy TableAdapter na potrzeby rozpoczęcia, zatwierdzania i wycofywania transakcji ADO.NET. Te metody używały wewnętrznego, ręcznie utworzonego SqlTransaction
obiektu, który został przypisany do obiektów TableAdapter SqlCommand
.
W tym samouczku sprawdzimy, jak uzyskać dostęp do ustawień połączenia z bazą danych i na poziomie polecenia w tableAdapter. W szczególności dodamy funkcje umożliwiające ProductsTableAdapter
dostęp do podstawowych ustawień parametry połączenia i limitu czasu polecenia.
Praca z danymi przy użyciu ADO.NET
.NET Framework firmy Microsoft zawiera mnóstwo klas zaprojektowanych specjalnie do pracy z danymi. Te klasy, znajdujące się w System.Data
przestrzeni nazw, są określane jako klasy ADO.NET. Niektóre klasy pod parasolem ADO.NET są powiązane z określonym dostawcą danych. Dostawcę danych można traktować jako kanał komunikacyjny, który umożliwia przepływ informacji między klasami ADO.NET a bazowym magazynem danych. Istnieją uogólnione dostawcy, tacy jak OleDb i ODBC, a także dostawcy specjalnie zaprojektowani dla określonego systemu bazy danych. Na przykład, chociaż istnieje możliwość nawiązania połączenia z bazą danych microsoft SQL Server przy użyciu dostawcy OleDb, dostawca SqlClient jest znacznie bardziej wydajny, ponieważ został zaprojektowany i zoptymalizowany specjalnie dla SQL Server.
W przypadku programowego uzyskiwania dostępu do danych często używany jest następujący wzorzec:
- Ustanów połączenie z bazą danych.
- Wydaj polecenie.
- W przypadku
SELECT
zapytań należy pracować z wynikowymi rekordami.
Istnieją oddzielne klasy ADO.NET do wykonywania każdego z tych kroków. Aby nawiązać połączenie z bazą danych przy użyciu dostawcy SqlClient, na przykład użyj SqlConnection
klasy . Aby wydać polecenie INSERT
, , UPDATE
DELETE
lub SELECT
do bazy danych, użyj SqlCommand
klasy .
Z wyjątkiem opakowujących modyfikacji bazy danych w ramach samouczka transakcji, nie musieliśmy pisać żadnego kodu ADO.NET niskiego poziomu, ponieważ kod wygenerowany automatycznie tableAdapters zawiera funkcje potrzebne do nawiązania połączenia z bazą danych, wystawiania poleceń, pobierania danych i wypełniania tych danych w tabelach DataTable. Jednak czasami konieczne może być dostosowanie tych ustawień niskiego poziomu. W ciągu następnych kilku kroków sprawdzimy, jak korzystać z obiektów ADO.NET używanych wewnętrznie przez klasy TableAdapters.
Krok 1. Badanie właściwości połączenia
Każda klasa TableAdapter ma właściwość określającą Connection
informacje o połączeniu z bazą danych. Ten typ danych i ConnectionString
wartość właściwości są określane przez opcje dokonane w Kreatorze konfiguracji tableAdapter. Pamiętaj, że po pierwszym dodaniu elementu TableAdapter do typu zestawu danych ten kreator prosi nas o źródło bazy danych (zobacz Rysunek 1). Lista rozwijana w tym pierwszym kroku zawiera te bazy danych określone w pliku konfiguracji, a także inne bazy danych w Connections danych Eksploratora serwera. Jeśli baza danych, której chcemy użyć, nie istnieje na liście rozwijanej, można określić nowe połączenie bazy danych, klikając przycisk Nowe połączenie i podając wymagane informacje o połączeniu.
Rysunek 1. Pierwszy krok Kreatora konfiguracji tableAdapter (kliknij, aby wyświetlić obraz pełnowymiarowy)
Poświęćmy chwilę na sprawdzenie kodu właściwości TableAdapter.Connection
Jak wspomniano w samouczku Tworzenie warstwy dostępu do danych , możemy wyświetlić automatycznie wygenerowany kod TableAdapter, przechodząc do okna Widok klas, przechodzenie do szczegółów odpowiedniej klasy, a następnie dwukrotne kliknięcie nazwy elementu członkowskiego.
Przejdź do okna Widok klasy, przechodząc do menu Widok i wybierając pozycję Widok klasy (lub wpisując klawisze Ctrl+Shift+C). W górnej połowie okna Widok klasy przejdź do NorthwindTableAdapters
obszaru nazw i wybierz klasę ProductsTableAdapter
. Spowoduje to wyświetlenie ProductsTableAdapter
elementów członkowskich w dolnej połowie widoku klasy, jak pokazano na rysunku 2. Kliknij dwukrotnie właściwość, Connection
aby wyświetlić jej kod.
Rysunek 2. Double-Click właściwości połączenia w widoku klasy, aby wyświetlić kod wygenerowany automatycznie
Właściwość TableAdapter i Connection
inny kod związany z połączeniem są następujące:
Private _connection As System.Data.SqlClient.SqlConnection
Private Sub InitConnection()
Me._connection = New System.Data.SqlClient.SqlConnection
Me._connection.ConnectionString = _
ConfigurationManager.ConnectionStrings("NORTHWNDConnectionString").ConnectionString
End Sub
Friend Property Connection() As System.Data.SqlClient.SqlConnection
Get
If (Me._connection Is Nothing) Then
Me.InitConnection
End If
Return Me._connection
End Get
Set
Me._connection = value
If (Not (Me.Adapter.InsertCommand) Is Nothing) Then
Me.Adapter.InsertCommand.Connection = value
End If
If (Not (Me.Adapter.DeleteCommand) Is Nothing) Then
Me.Adapter.DeleteCommand.Connection = value
End If
If (Not (Me.Adapter.UpdateCommand) Is Nothing) Then
Me.Adapter.UpdateCommand.Connection = value
End If
Dim i As Integer = 0
Do While (i < Me.CommandCollection.Length)
If (Not (Me.CommandCollection(i)) Is Nothing) Then
CType(Me.CommandCollection(i), _
System.Data.SqlClient.SqlCommand).Connection = value
End If
i = (i + 1)
Loop
End Set
End Property
Po utworzeniu wystąpienia klasy TableAdapter zmienna _connection
składowa jest równa Nothing
. Po korzystaniu z Connection
właściwości najpierw sprawdza, czy zmienna _connection
składowa została utworzone. Jeśli tak nie jest, InitConnection
metoda jest wywoływana, która tworzy wystąpienie _connection
i ustawia jej ConnectionString
właściwość na wartość parametry połączenia określoną w pierwszym kroku kreatora konfiguracji TableAdapter.
Właściwość Connection
można również przypisać do SqlConnection
obiektu. Powoduje to skojarzenie nowego SqlConnection
obiektu z każdym z obiektów TableAdapter SqlCommand
.
Krok 2. Uwidacznianie ustawień Connection-Level
Informacje o połączeniu powinny pozostać hermetyzowane w tableAdapter i nie mogą być dostępne dla innych warstw w architekturze aplikacji. Jednak mogą wystąpić scenariusze, gdy informacje o poziomie połączenia usługi TableAdapter muszą być dostępne lub można je dostosować dla strony zapytania, użytkownika lub ASP.NET.
Rozszerzmy ProductsTableAdapter
element w zestawie Northwind
danych, aby uwzględnić ConnectionString
właściwość, która może być używana przez warstwę logiki biznesowej do odczytu lub zmiany parametry połączenia używanych przez tableAdapter.
Uwaga
Parametry połączenia to parametry, które określają informacje o połączeniu z bazą danych, takie jak dostawca do użycia, lokalizacja bazy danych, poświadczenia uwierzytelniania i inne ustawienia związane z bazą danych. Aby uzyskać listę wzorców parametry połączenia używanych przez różne magazyny danych i dostawców, zobacz ConnectionStrings.com.
Zgodnie z opisem w samouczku Tworzenie warstwy dostępu do danych można rozszerzyć klasy generowane automatycznie przez zestaw danych typu za pomocą klas częściowych. Najpierw utwórz nowy podfolder w projekcie o nazwie ConnectionAndCommandSettings
poniżej ~/App_Code/DAL
folderu.
Rysunek 3. Dodawanie podfolderu o nazwie ConnectionAndCommandSettings
Dodaj nowy plik klasy o nazwie ProductsTableAdapter.ConnectionAndCommandSettings.vb
i wprowadź następujący kod:
Namespace NorthwindTableAdapters
Partial Public Class ProductsTableAdapter
Public Property ConnectionString() As String
Get
Return Me.Connection.ConnectionString
End Get
Set(ByVal value As String)
Me.Connection.ConnectionString = value
End Set
End Property
End Class
End Namespace
Ta klasa częściowa dodaje Public
właściwość o nazwie ConnectionString
do ProductsTableAdapter
klasy, która umożliwia każdej warstwie odczytywanie lub aktualizowanie parametry połączenia dla połączenia bazowego tableAdapter.
Po utworzeniu tej częściowej klasy (i zapisaniu) otwórz klasę ProductsBLL
. Przejdź do jednej z istniejących metod i wpisz ciąg , Adapter
a następnie naciśnij klucz okresu, aby wyświetlić funkcję IntelliSense. Powinna zostać wyświetlona nowa ConnectionString
właściwość dostępna w funkcji IntelliSense, co oznacza, że można programowo odczytywać lub dostosowywać tę wartość z usługi BLL.
Uwidacznianie całego obiektu połączenia
Ta klasa częściowa uwidacznia tylko jedną właściwość bazowego obiektu połączenia: ConnectionString
. Jeśli chcesz udostępnić cały obiekt połączenia poza granicami tabeli TableAdapter, możesz również zmienić Connection
poziom ochrony właściwości. Kod wygenerowany automatycznie w kroku 1 pokazał, że właściwość TableAdapter Connection
jest oznaczona jako Friend
, co oznacza, że można uzyskać do niej dostęp tylko przez klasy w tym samym zestawie. Można to jednak zmienić za pomocą właściwości TableAdapter.ConnectionModifier
Otwórz zestaw Northwind
danych, kliknij ProductsTableAdapter
element w Projektant i przejdź do okno Właściwości. W tym miejscu zostanie wyświetlony zestaw wartości domyślnej ConnectionModifier
. Assembly
Aby udostępnić Connection
właściwość poza zestawem Typed DataSet, zmień ConnectionModifier
właściwość na Public
.
Rysunek 4. Connection
Poziom ułatwień dostępu właściwości można skonfigurować za pośrednictwem ConnectionModifier
właściwości (kliknij, aby wyświetlić obraz pełnowymiarowy)
Zapisz zestaw danych, a następnie wróć do ProductsBLL
klasy. Tak jak wcześniej, przejdź do jednej z istniejących metod i wpisz, Adapter
a następnie naciśnij klawisz kropki, aby wyświetlić funkcję IntelliSense. Lista powinna zawierać Connection
właściwość, co oznacza, że można teraz programowo odczytywać lub przypisywać dowolne ustawienia na poziomie połączenia z usługi BLL.
Krok 3. Badanie właściwości Command-Related
TabelaAdapter składa się z głównego zapytania, które domyślnie ma automatycznie generowane INSERT
instrukcje , UPDATE
i DELETE
. To główne zapytanie s INSERT
, UPDATE
i DELETE
instrukcje są implementowane w kodzie TableAdapter jako obiekt karty danych ADO.NET za pośrednictwem Adapter
właściwości. Podobnie jak we właściwości Connection
, Adapter
typ danych właściwości jest określany przez używanego dostawcę danych. Ponieważ te samouczki używają dostawcy SqlClient, Adapter
właściwość jest typu SqlDataAdapter
.
Właściwość TableAdapter ma Adapter
trzy właściwości typu SqlCommand
, których używa do wystawiania instrukcji INSERT
, UPDATE
i DELETE
:
InsertCommand
UpdateCommand
DeleteCommand
SqlCommand
Obiekt jest odpowiedzialny za wysyłanie określonego zapytania do bazy danych i ma właściwości takie jak : CommandText
, który zawiera instrukcję AD-hoc SQL lub procedurę składowaną do wykonania; i Parameters
, która jest kolekcją SqlParameter
obiektów. Jak widzieliśmy już w samouczku Tworzenie warstwy dostępu do danych, te obiekty poleceń można dostosować za pomocą okno Właściwości.
Oprócz głównego zapytania tableAdapter może zawierać zmienną liczbę metod, które po wywołaniu wysyłają określone polecenie do bazy danych. Główny obiekt polecenia zapytania i obiekty poleceń dla wszystkich dodatkowych metod są przechowywane we właściwości TableAdapter s CommandCollection
.
Przyjrzyjmy się kodowi wygenerowanemu przez ProductsTableAdapter
element DataSet Northwind
dla tych dwóch właściwości i ich pomocniczych zmiennych składowych i metod pomocniczych:
Private WithEvents _adapter As System.Data.SqlClient.SqlDataAdapter
Private Sub InitAdapter()
Me._adapter = New System.Data.SqlClient.SqlDataAdapter
... Code that creates the InsertCommand, UpdateCommand, ...
... and DeleteCommand instances - omitted for brevity ...
End Sub
Private ReadOnly Property Adapter() As System.Data.SqlClient.SqlDataAdapter
Get
If (Me._adapter Is Nothing) Then
Me.InitAdapter
End If
Return Me._adapter
End Get
End Property
Private _commandCollection() As System.Data.SqlClient.SqlCommand
Private Sub InitCommandCollection()
Me._commandCollection = New System.Data.SqlClient.SqlCommand(8) {}
... Code that creates the command objects for the main query and the ...
... ProductsTableAdapter�s other eight methods - omitted for brevity ...
End Sub
Protected ReadOnly Property CommandCollection() As System.Data.SqlClient.SqlCommand()
Get
If (Me._commandCollection Is Nothing) Then
Me.InitCommandCollection
End If
Return Me._commandCollection
End Get
End Property
Kod właściwości Adapter
i CommandCollection
ściśle naśladuje Connection
właściwość . Istnieją zmienne składowe, które przechowują obiekty używane przez właściwości. Metody dostępu właściwości Get
zaczynają się od sprawdzenia, czy odpowiednia zmienna składowa to Nothing
. Jeśli tak, wywoływana jest metoda inicjowania, która tworzy wystąpienie zmiennej składowej i przypisuje podstawowe właściwości związane z poleceniami.
Krok 4. Uwidacznianie ustawień Command-Level
W idealnym przypadku informacje na poziomie polecenia powinny pozostać hermetyzowane w warstwie dostępu do danych. Jeśli jednak te informacje będą potrzebne w innych warstwach architektury, mogą być uwidocznione za pośrednictwem klasy częściowej, podobnie jak w przypadku ustawień na poziomie połączenia.
Ponieważ obiekt TableAdapter ma tylko jedną Connection
właściwość, kod uwidaczniania ustawień na poziomie połączenia jest dość prosty. Elementy są nieco bardziej skomplikowane podczas modyfikowania ustawień na poziomie polecenia, ponieważ obiekt TableAdapter może mieć wiele obiektów poleceń — InsertCommand
obiektów , UpdateCommand
i DeleteCommand
, wraz ze zmienną liczbą obiektów poleceń we CommandCollection
właściwości . Podczas aktualizowania ustawień na poziomie polecenia te ustawienia należy propagować do wszystkich obiektów poleceń.
Załóżmy na przykład, że w tableAdapter istniały pewne zapytania, które trwały wyjątkowo długo. W przypadku używania obiektu TableAdapter do wykonywania jednego z tych zapytań warto zwiększyć właściwość obiektu CommandTimeout
polecenia. Ta właściwość określa liczbę sekund oczekiwania na wykonanie polecenia, a wartość domyślna to 30.
Aby umożliwić CommandTimeout
dostosowanie właściwości przez bibliotekę BLL, dodaj następującą Public
metodę do ProductsDataTable
metody przy użyciu pliku klasy częściowej utworzonego w kroku 2 (ProductsTableAdapter.ConnectionAndCommandSettings.vb
):
Public Sub SetCommandTimeout(ByVal timeout As Integer)
If Me.Adapter.InsertCommand IsNot Nothing Then
Me.Adapter.InsertCommand.CommandTimeout = timeout
End If
If Me.Adapter.DeleteCommand IsNot Nothing Then
Me.Adapter.DeleteCommand.CommandTimeout = timeout
End If
If Me.Adapter.UpdateCommand IsNot Nothing Then
Me.Adapter.UpdateCommand.CommandTimeout = timeout
End If
For i As Integer = 0 To Me.CommandCollection.Length - 1
If Me.CommandCollection(i) IsNot Nothing Then
Me.CommandCollection(i).CommandTimeout = timeout
End If
Next
End Sub
Tę metodę można wywołać z warstwy BLL lub warstwy prezentacji, aby ustawić limit czasu polecenia dla wszystkich problemów z poleceniami przez to wystąpienie tableAdapter.
Uwaga
Właściwości Adapter
i CommandCollection
są oznaczone jako Private
, co oznacza, że można uzyskać do nich dostęp tylko z kodu w elemecie TableAdapter. Connection
W przeciwieństwie do właściwości te modyfikatory dostępu nie są konfigurowalne. W związku z tym, jeśli musisz uwidocznić właściwości na poziomie polecenia do innych warstw w architekturze, należy użyć metody częściowej omówionej powyżej w celu udostępnienia Public
metody lub właściwości, która odczytuje lub zapisuje w Private
obiektach poleceń.
Podsumowanie
Klasy TableAdapters w typowanym zestawie danych służą do hermetyzacji szczegółów i złożoności dostępu do danych. Używając elementów TableAdapters, nie musimy martwić się o pisanie kodu ADO.NET w celu nawiązania połączenia z bazą danych, wystawienie polecenia lub wypełnienie wyników w tabeli DataTable. To wszystko jest obsługiwane automatycznie dla nas.
Może jednak wystąpić potrzeba dostosowania ADO.NET ADO.NET niskiego poziomu, takich jak zmiana parametry połączenia lub domyślne wartości limitu czasu połączenia lub polecenia. Obiekt TableAdapter ma automatycznie generowane Connection
właściwości , Adapter
i CommandCollection
, ale domyślnie są to lub Friend
Private
. Te informacje wewnętrzne można uwidocznić przez rozszerzenie klasy TableAdapter przy użyciu klas częściowych w celu uwzględnienia Public
metod lub właściwości. Alternatywnie modyfikator dostępu do właściwości TableAdapter Connection
można skonfigurować za pomocą właściwości TableAdapter.ConnectionModifier
Szczęśliwe programowanie!
Informacje o autorze
Scott Mitchell, autor siedmiu książek ASP/ASP.NET i założyciel 4GuysFromRolla.com, współpracuje z technologiami internetowymi firmy Microsoft od 1998 roku. Scott pracuje jako niezależny konsultant, trener i pisarz. Jego najnowsza książka to Sams Teach Yourself ASP.NET 2.0 w ciągu 24 godzin. Można do niego dotrzeć pod adresem mitchell@4GuysFromRolla.com. Lub za pośrednictwem swojego bloga, który można znaleźć na stronie http://ScottOnWriting.NET.
Specjalne podziękowania
Ta seria samouczków została przejrzyona przez wielu przydatnych recenzentów. Głównymi recenzentami tego samouczka byli Burnadette Leigh, S ren Jacob Lauritsen, Teresa Murphy i Hilton Geisenow. Chcesz przejrzeć nadchodzące artykuły MSDN? Jeśli tak, upuść mi wiersz pod adresemmitchell@4GuysFromRolla.com .