TN053: niestandardowe procedury DFX dla klas baz danych DAO
Uwaga
DaO jest używany z bazami danych programu Access i jest obsługiwany za pośrednictwem pakietu Office 2013. DaO 3.6 jest wersją ostateczną i jest uważany za przestarzałą. Środowisko i kreatory języka Visual C++ nie obsługują dao (chociaż klasy DAO są uwzględnione i nadal można ich używać). Firma Microsoft zaleca używanie szablonów OLE DB lub ODBC i MFC dla nowych projektów. W przypadku obsługi istniejących aplikacji należy używać tylko dao.
Ta uwaga techniczna opisuje mechanizm wymiany pól rekordów DAO (DFX). Aby lepiej zrozumieć, co dzieje się w procedurach DFX, DFX_Text
funkcja zostanie szczegółowo wyjaśniona jako przykład. Jako dodatkowe źródło informacji do tej uwagi technicznej można sprawdzić kod dla innych funkcji DFX. Prawdopodobnie nie będzie potrzebna niestandardowa rutyna DFX tak często, jak może być potrzebna niestandardowa rutyna RFX (używana z klasami baz danych ODBC).
Ta uwaga techniczna zawiera:
Omówienie systemu plików DFX
Przykłady użycia wymiany pól rekordów DAO i powiązania dynamicznego
Omówienie systemu plików DFX
Mechanizm wymiany pól rekordów DAO (DFX) służy do uproszczenia procedury pobierania i aktualizowania danych podczas korzystania z CDaoRecordset
klasy. Proces ten jest uproszczony przy użyciu składowych CDaoRecordset
danych klasy. Wyprowadzając z CDaoRecordset
klasy , można dodać składowe danych do klasy pochodnej reprezentującej każde pole w tabeli lub zapytaniu. Ten mechanizm "powiązania statycznego" jest prosty, ale może nie być metodą pobierania/aktualizowania danych dla wszystkich aplikacji. DfX pobiera każde pole powiązane za każdym razem, gdy bieżący rekord jest zmieniany. Jeśli tworzysz aplikację wrażliwą na wydajność, która nie wymaga pobierania każdego pola po zmianie waluty, "powiązanie dynamiczne" za pośrednictwem metody CDaoRecordset::GetFieldValue
i CDaoRecordset::SetFieldValue
może być wybraną metodą dostępu do danych.
Uwaga
Powiązania dfX i dynamiczne nie wykluczają się wzajemnie, więc można użyć hybrydowego użycia powiązania statycznego i dynamicznego.
Przykład 1 — używanie tylko wymiany pól rekordów DAO
(zakłada, CDaoRecordset
że — klasa CMySet
pochodna jest już otwarta)
// Add a new record to the customers table
myset.AddNew();
myset.m_strCustID = _T("MSFT");
myset.m_strCustName = _T("Microsoft");
myset.Update();
Przykład 2 — używanie tylko powiązania dynamicznego
(zakłada użycie CDaoRecordset
klasy , rs
i jest już otwarte)
// Add a new record to the customers table
COleVariant varFieldValue1 (_T("MSFT"),
VT_BSTRT);
//Note: VT_BSTRT flags string type as ANSI,
instead of UNICODE default
COleVariant varFieldValue2 (_T("Microsoft"),
VT_BSTRT);
rs.AddNew();
rs.SetFieldValue(_T("Customer_ID"),
varFieldValue1);
rs.SetFieldValue(_T("Customer_Name"),
varFieldValue2);
rs.Update();
Przykład 3 — używanie wymiany pól rekordów DAO i powiązania dynamicznego
(zakłada przeglądanie danych pracowników za pomocą CDaoRecordset
klasy emp
pochodnej )
// Get the employee's data so that it can be displayed
emp.MoveNext();
// If user wants to see employee's photograph,
// fetch it
COleVariant varPhoto;
if (bSeePicture)
emp.GetFieldValue(_T("photo"),
varPhoto);
// Display the data
PopUpEmployeeData(emp.m_strFirstName,
emp.m_strLastName,
varPhoto);
Jak działa system DFX
Mechanizm DFX działa podobnie do mechanizmu wymiany pól rekordów (RFX) używanego przez klasy MFC ODBC. Zasady DFX i RFX są takie same, ale istnieją liczne różnice wewnętrzne. Projekt funkcji DFX był taki, że praktycznie cały kod jest współużytkowany przez poszczególne procedury DFX. Na najwyższym poziomie dfX wykonuje tylko kilka rzeczy.
DfX konstruuje klauzulę SQL SELECT i klauzulę SQL PARAMETERS w razie potrzeby.
DfX konstruuje strukturę powiązań używaną przez funkcję dao
GetRows
(więcej na ten temat później).DfX zarządza buforem danych używanym do wykrywania zanieczyszczonych pól (jeśli używane jest podwójne buforowanie)
DfX zarządza tablicami stanu NULL i DIRTY oraz ustawia wartości w razie potrzeby w przypadku aktualizacji.
Sercem mechanizmu DFX jest funkcja klasy pochodnej CDaoRecordset
DoFieldExchange
. Ta funkcja wysyła wywołania do poszczególnych funkcji DFX odpowiedniego typu operacji. Przed wywołaniem DoFieldExchange
wewnętrznych funkcji MFC ustaw typ operacji. Na poniższej liście przedstawiono różne typy operacji i krótki opis.
Działanie | opis |
---|---|
AddToParameterList |
Builds PARAMETERS, klauzula |
AddToSelectList |
Kompiluje klauzulę SELECT |
BindField |
Konfiguruje strukturę powiązań |
BindParam |
Ustawia wartości parametrów |
Fixup |
Ustawia stan NULL |
AllocCache |
Przydziela pamięć podręczną na potrzeby brudnego sprawdzania |
StoreField |
Zapisuje bieżący rekord w pamięci podręcznej |
LoadField |
Przywraca pamięć podręczną do wartości składowych |
FreeCache |
Bezpłatna pamięć podręczna |
SetFieldNull |
Ustawia stan i wartość pola na wartość NULL |
MarkForAddNew |
Oznacza pola zanieczyszczone, jeśli nie MA WARTOŚCI PSEUDO NULL |
MarkForEdit |
Oznacza pola zanieczyszczone, jeśli nie są zgodne z pamięcią podręczną |
SetDirtyField |
Ustawia wartości pól oznaczone jako zanieczyszczone |
W następnej sekcji każda operacja zostanie szczegółowo wyjaśniona dla elementu DFX_Text
.
Najważniejszą funkcją do zrozumienia procesu wymiany pól rekordów CDaoRecordset
DAO jest użycie GetRows
funkcji obiektu. Funkcja DAO GetRows
może działać na kilka sposobów. Ta uwaga techniczna będzie krótko opisywana GetRows
, ponieważ wykracza poza zakres tej uwagi technicznej.
DaO GetRows
może działać na kilka sposobów.
Może pobierać wiele rekordów i wiele pól danych jednocześnie. Dzięki temu można szybciej uzyskiwać dostęp do danych z komplikacjami dotyczącymi obsługi dużej struktury danych i odpowiednich przesunięć do każdego pola i dla każdego rekordu danych w strukturze. MFC nie korzysta z tego mechanizmu pobierania wielu rekordów.
Innym sposobem
GetRows
może być umożliwienie programistom określania adresów powiązań dla pobranych danych każdego pola dla jednego rekordu danych.DaO będzie również "wywołać z powrotem" do obiektu wywołującego dla kolumn o zmiennej długości, aby umożliwić obiektowi wywołującym przydzielanie pamięci. Ta druga funkcja ma korzyść z zminimalizowania liczby kopii danych, a także umożliwienia bezpośredniego przechowywania danych w składowych klasy (klasy pochodnej
CDaoRecordset
). Ten drugi mechanizm jest metodą MFC używa do powiązania z elementami członkowskimi danych wCDaoRecordset
klasach pochodnych.
Co robi niestandardowa rutyna DFX
Z tej dyskusji wynika, że najważniejszą operacją zaimplementowaną w dowolnej funkcji DFX musi być możliwość skonfigurowania wymaganych struktur danych w celu pomyślnego wywołania metody GetRows
. Istnieje wiele innych operacji, które funkcja DFX musi również obsługiwać, ale żadna z nich nie jest tak ważna lub złożona, jak poprawnie przygotowuje się do GetRows
wywołania.
Korzystanie z systemu DFX zostało opisane w dokumentacji online. Zasadniczo istnieją dwa wymagania. Najpierw należy dodać składowe do klasy pochodnej CDaoRecordset
dla każdego powiązanego pola i parametru. Po wykonaniu tej czynności CDaoRecordset::DoFieldExchange
należy przesłonić. Należy pamiętać, że typ danych elementu członkowskiego jest ważny. Powinny być zgodne z danymi z pola w bazie danych lub co najmniej być konwertowane na ten typ. Na przykład pole liczbowe w bazie danych, takie jak długa liczba całkowita, zawsze można przekonwertować na tekst i powiązać z elementem CString
członkowskim, ale pole tekstowe w bazie danych nie musi być konwertowane na reprezentację liczbową, taką jak długa liczba całkowita i powiązana z długim elementem członkowskim liczby całkowitej. DaO i aparat bazy danych Microsoft Jet są odpowiedzialne za konwersję (a nie MFC).
Szczegóły DFX_Text
Jak wspomniano wcześniej, najlepszym sposobem wyjaśnienia sposobu działania systemu plików DFX jest praca z przykładem. W tym celu przechodzenie przez wewnętrzne elementy DFX_Text
programu powinno działać całkiem dobrze, aby ułatwić przynajmniej podstawową wiedzę na temat systemu PLIKÓW DFX.
AddToParameterList
Ta operacja tworzy klauzulę SQL PARAMETERS ("
Parameters <param name>, <param type> ... ;
") wymaganą przez narzędzie Jet. Każdy parametr ma nazwę i wpisze (zgodnie z opisem w wywołaniu RFX). Zobacz funkcję funkcjiCDaoFieldExchange::AppendParamType
, aby wyświetlić nazwy poszczególnych typów. W przypadku parametruDFX_Text
używany typ to tekst.AddToSelectList
Tworzy klauzulę SQL SELECT . Jest to dość proste, ponieważ nazwa kolumny określona przez wywołanie DFX jest po prostu dołączana ("
SELECT <column name>, ...
").BindField
Najbardziej złożone operacje. Jak wspomniano wcześniej, jest to miejsce, w którym skonfigurowana jest struktura powiązań DAO używana przez
GetRows
program . Jak widać w kodzie w typach informacji wDFX_Text
strukturze, są używane typy dao (DAO_CHAR lub DAO_WCHAR w przypadkuDFX_Text
). Ponadto konfigurowany jest również typ używanego powiązania. W poprzedniej sekcjiGetRows
opisano tylko krótko, ale wystarczyło wyjaśnić, że typ powiązania używanego przez MFC jest zawsze bezpośrednim powiązaniem adresów (DAOBINDING_DIRECT). Ponadto w przypadku powiązania kolumn o zmiennej długości (na przykładDFX_Text
) jest używane powiązanie wywołania zwrotnego, dzięki czemu MFC może kontrolować alokację pamięci i określać adres prawidłowej długości. Oznacza to, że MFC zawsze może powiedzieć DAO "gdzie" umieścić dane, umożliwiając powiązanie bezpośrednio ze zmiennymi składowymi. Pozostała część struktury powiązań jest wypełniona elementami, takimi jak adres funkcji wywołania zwrotnego alokacji pamięci oraz typ powiązania kolumny (powiązanie według nazwy kolumny).BindParam
Jest to prosta operacja, która wywołuje
SetParamValue
wartość parametru określoną w elemencie członkowskim parametru.Fixup
Wypełnia stan NULL dla każdego pola.
SetFieldNull
Ta operacja oznacza tylko każdy stan pola jako NULL i ustawia wartość zmiennej składowej na PSEUDO_NULL.
SetDirtyField
Wywołuje
SetFieldValue
każde pole oznaczone jako zanieczyszczone.
Wszystkie pozostałe operacje dotyczą tylko korzystania z pamięci podręcznej danych. Pamięć podręczna danych jest dodatkowym buforem danych w bieżącym rekordzie, który jest używany do uproszczenia niektórych rzeczy. Na przykład pola "brudne" można wykryć automatycznie. Zgodnie z opisem w dokumentacji online można ją całkowicie wyłączyć lub na poziomie pola. Implementacja buforu wykorzystuje mapę. Ta mapa służy do dopasowywania dynamicznie przydzielonych kopii danych z adresem pola "powiązane" (lub CDaoRecordset
pochodnego elementu członkowskiego danych).
AllocCache
Dynamicznie przydziela wartość pola buforowanego i dodaje ją do mapy.
FreeCache
Usuwa wartość pola z pamięci podręcznej i usuwa ją z mapy.
StoreField
Kopiuje bieżącą wartość pola do pamięci podręcznej danych.
LoadField
Kopiuje buforowana wartość do elementu członkowskiego pola.
MarkForAddNew
Sprawdza, czy bieżąca wartość pola ma wartość inną niż NULL i w razie potrzeby oznacza, że jest ona zanieczyszczona.
MarkForEdit
Porównuje bieżącą wartość pola z pamięcią podręczną danych i oznacza zanieczyszczone w razie potrzeby.
Napiwek
Modelowanie niestandardowych procedur DFX dla istniejących procedur DFX dla standardowych typów danych.
Zobacz też
Uwagi techniczne według numerów
Uwagi techniczne według kategorii