Udostępnij za pośrednictwem


Konfigurowanie ustawień na poziomie połączenia i poleceń warstwy dostępu do danych (VB)

Autor: Scott Mitchell

Pobierz plik PDF

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:

  1. Ustanów połączenie z bazą danych.
  2. Wydaj polecenie.
  3. 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, , UPDATEDELETElub 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.

Pierwszy krok Kreatora konfiguracji tableAdapter

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.

Kliknij dwukrotnie właściwość połączenia w widoku klasy, aby wyświetlić kod wygenerowany automatycznie

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.

Dodawanie podfolderu o nazwie ConnectionAndCommandSettings

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.

Poziom ułatwień dostępu właściwości połączenia można skonfigurować za pośrednictwem właściwości ConnectionModifier

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.

TabelaAdapter składa się z głównego zapytania, które domyślnie ma automatycznie generowane INSERTinstrukcje , UPDATEi DELETE . To główne zapytanie s INSERT, UPDATEi 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, UPDATEi 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ń — InsertCommandobiektów , UpdateCommandi 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 CommandTimeoutpolecenia. 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 Connectionwłaściwości , Adapteri CommandCollection , ale domyślnie są to lub FriendPrivate. 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 .