Basit Tüketici Uygulama
Aşağıdaki konular basit bir tüketici oluşturmak için MFC Uygulaması Sihirbazı ve ATL OLE DB Tüketici Sihirbazı tarafından oluşturulan dosyaların nasıl düzenlendiğini gösterir. Bu örneğin aşağıdaki bölümleri vardır:
"Müşteri İle Verileri Alma" tüm verileri bir veritabanı tablosundan satır satır okuyan müşteriye kodun nasıl uygulanacağını gösterir.
"Müşteriye Yer imi Desteği Ekleme" müşteriye nasıl yer imi desteği ekleneceğini gösterir.
"Müşteriye XML Desteği Ekleme" alınmış satır kümesi verilerinin XML verileri olarak çıkarılması için müşteri kodunun nasıl değiştirileceğini gösterir.
Not
Bu bölümde açıklanan tüketici uygulamasını MyProv ve Provider örnek sağlayıcılarını test etmek için kullanabilirsiniz.
Not
MyProv' u (Basit Salt-Okunur Sağlayıcıyı Geliştirmek bağlantısında açıklanan aynı sağlayıcı) test etmek üzere bir tüketici oluşturmak için "Tüketiciye Yer İmi Desteği Eklemek"'te açıklandığı gibi yer imi desteğini de eklemeniz gerekir.
Not
Sağlayıcıyı test etmek üzere bir tüketici uygulama oluşturmak için "Tüketiciye Yer İmi Desteği Eklemek"'teki yer imi desteğini bırakıp "Tüketiciye XML Desteği Eklemek"'e geçmeniz gerekir.
Tüketici ile Veri Alma
OLE DB tüketicisini kullanacak konsol uygulamasını değiştirmek için
MyCons.cpp öğesinde kalın metni aşağıdaki şekilde ekleyerek ana kodu değiştirin:
// MyCons.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "Products.h" ... int main(int argc, char* argv[]) { HRESULT hr = CoInitialize(NULL); // Instantiate rowset CProducts rs; hr = rs.OpenAll(); ATLASSERT( SUCCEEDED( hr ) ); hr = rs.MoveFirst(); // Iterate through the rowset while( SUCCEEDED(hr) && hr != DB_S_ENDOFROWSET ) { // Print out the column information for each row printf("Product ID: %d, Name: %s, Unit Price: %d, Quantity per Unit: %d, Units in Stock %d, Reorder Level %d\n", rs.m_ProductID, rs.m_ProductName, rs.m_UnitPrice, rs.m_QuantityPerUnit, rs.m_UnitsInStock, rs.m_ReorderLevel ); hr = rs.MoveNext(); } rs.Close(); rs.ReleaseCommand(); CoUninitialize(); return 0; }
Tüketiciye Yer İmi Desteği Sağlama
Yer imi, tablodaki satırları benzersiz şekilde tanımlayan bir sütundur. Tipik olarak bu anahtar sütundur. Fakat her zaman değildir: bu sağlayıcıya özeldir. Bu bölüm nasıl yer imi desteği ekleyeceğinizi göstermektedir. Bunu yapmak için kullanıcı kayıt sınıfında aşağıdakileri yapmanız gerekir:
Yer imini oluştur. Bunlar CBookmark türüne ilişkin nesnelerdir.
DBPROP_IRowsetLocate özelliğini ayarlayarak sağlayıcıdan bir yer işareti sütunu isteyin.
BOOKMARK_ENTRY makrosunu kullanarak sütun haritasına bir yer imi girişi ekleyin.
Önceki adımlar size çalışmak için yer işaretleri desteği ve bir yer işaretleri nesnesi verir. Bu kod örneği, aşağıdaki gibi bir yer işareti gösterir:
Yazmak için bir dosya açın.
Satır kümesi verilerini dosyaya satır satır çıktı olarak ver.
MoveToBookmark komutuyla satır kümesi imlecini yer işaretinin üzerine getirin.
Yer işaretli alanları dosyanın en sonuna ekleyerek çıktı olarak ver.
Not
Bu tüketici uygulama sağlayıcısı örnek sağlayıcısı uygulama sınamak için kullanırsanız, bu bölümde açıklanan yer imi desteğini atlayın.
Yer imini oluşturmak için
Erişimcinin CBookmark türünde bir nesne içermesi gereklidir. nSize parametresi, yer işareti arabelleğinin boyutunu bayt cinsinden (genellikle 32 bitlik platformlar için 4 ve 64 bitlik platformlar için 8) belirtir. Aşağıdaki bildirimi kullanıcı kayıt sınıfındaki sütun veri üyelerine ekleyin:
////////////////////////////////////////////////////////////////////// // Products.h class CProductsAccessor { public: CBookmark<4> m_bookmark; // Add bookmark declaration LONG m_ProductID; ...
Sağlayıcıdan bir yer imi sütunu istemek için
Aşağıdaki kodu kullanıcı kayıt sınıfındaki GetRowsetProperties yöntemine ekleyin:
// Set the DBPROP_IRowsetLocate property. void GetRowsetProperties(CDBPropSet* pPropSet) { pPropSet->AddProperty(DBPROP_CANFETCHBACKWARDS, true, DBPROPOPTIONS_OPTIONAL); pPropSet->AddProperty(DBPROP_CANSCROLLBACKWARDS, true, DBPROPOPTIONS_OPTIONAL); // Add DBPROP_IRowsetLocate property to support bookmarks pPropSet->AddProperty(DBPROP_IRowsetLocate, true); }
Sütun haritasına bir yer imi eklemek için
Aşağıdaki girdiyi kullanıcı kayıt sınıfındaki sütun haritasına ekleyin:
// Set a bookmark entry in the column map. BEGIN_COLUMN_MAP(CProductsAccessor) BOOKMARK_ENTRY(m_bookmark) // Add bookmark entry COLUMN_ENTRY_LENGTH_STATUS(1, m_ProductID, m_dwProductIDLength, m_dwProductIDStatus) COLUMN_ENTRY_LENGTH_STATUS(2, m_ProductName, m_dwProductNameLength, m_dwProductNameStatus) ... END_COLUMN_MAP()
Ana kodunuzda bir yer imi kullanmak için
Önceden oluşturduğunuz konsol uygulamasındaki MyCons.cpp dosyasında aşağıdaki gibi okumak üzere ana kodu değiştirin. Yer imlerini kullanmak için ana kodun erişimcidekinden (m_bookmark) farklı bir yer imi olan kendi yer imi nesnesini (myBookmark) oluşturması gerekir.
/////////////////////////////////////////////////////////////////////// // MyCons.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "Products.h" #include <iostream> #include <fstream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { HRESULT hr = CoInitialize(NULL); // Instantiate rowset CProducts rs; hr = rs.OpenAll(); hr = rs.MoveFirst(); // Cast CURRENCY m_UnitPrice to a long value LONGLONG lPrice = rs.m_UnitPrice.int64; // Open file output.txt for writing in overwrite mode ofstream outfile( "C:\\output.txt", ios::out ); if (!outfile) // Test for invalid file return -1; // Instantiate a bookmark object myBookmark for the main code CBookmark<4> myBookmark; int nCounter = 0; // Iterate through the rowset and output column data to output.txt row by row // In the file, mark the beginning of this set of data: outfile << "initial row dump" << endl; while( SUCCEEDED(hr) && hr != DB_S_ENDOFROWSET ) { nCounter++; if( nCounter == 5 ) myBookmark = rs.bookmark; // Output the column information for each row: outfile << rs.m_ProductID << rs.m_ProductName << lPrice << rs.m_QuantityPerUnit << rs.m_UnitsInStock << rs.m_ReorderLevel << endl; hr = rs.MoveNext(); } // Move cursor to bookmark hr = rs.MoveToBookmark(myBookmark); // Iterate through the rowset and output column data to output.txt row by row // In the file, mark the beginning of this set of data: outfile << "row dump starting from bookmarked row" << endl; while( SUCCEEDED(hr) && hr != DB_S_ENDOFROWSET ) { // Output the column information for each row outfile << rs.m_ProductID << rs.m_ProductName << lPrice << rs.m_QuantityPerUnit << rs.m_UnitsInStock << rs.m_ReorderLevel << endl; hr = rs.MoveNext(); } rs.CloseAll(); CoUninitialize(); return 0; }
Yer imleri hakkında daha fazla bilgi için bkz. Yer İmlerini Kullanma. Yer imi örnekleri aynı zamanda Satır Kümelerini Güncelleştirme bölümünde de gösterilmiştir.
Tüketiciye XML Desteği Sağlama
XML verilerine erişim'de anlatıldığı gibi, XML verilerini bir veri kaynağından almanın iki yolu vardır: CStreamRowset öğesini kullanmak, ya da CXMLAccessor öğesini kullanmak. Bu örnek, daha etkili olan fakat bu örnek uygulamayı yürüttüğünüz bilgisayarda SQL Server 2000 çalıştırmanızı gerektiren CStreamRowset kullanır.
CStreamRowset'ten devralacak olan komut sınıfını değiştirmek için
Önceden oluşturduğunuz tüketici uygulamasında, CCommand bildiriminizi, şu şekilde,CStreamRowset öğesini satır kümesi sınıfı olarak belirtmek için değiştirin:
class CProducts : public CCommand<CAccessor<CProductsAccessor>, CStreamRowset >
Ana kodu XML veriyi almak ve çıkarmak üzere değiştirmek için
Önceden oluşturduğunuz konsol uygulamasındaki MyCons.cpp dosyasında aşağıdaki gibi okumak üzere ana kodu değiştirin:
/////////////////////////////////////////////////////////////////////// // MyCons.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "Products.h" #include <iostream> #include <fstream> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { HRESULT hr = CoInitialize(NULL); // Instantiate rowset CProducts rs; // Add variable declarations for the Read method to handle sequential stream data CHAR buffer[1001]; // Pointer to buffer into which data stream is read ULONG cbRead; // Actual number of bytes read from the data stream hr = rs.OpenAll(); // Open file output.txt for writing in overwrite mode ofstream outfile( "C:\\output.txt", ios::out ); if (!outfile) // Test for invalid file return -1; // The following loop reads 1000 bytes of the data stream at a time // until it reaches the end of the data stream for (;;) { // Read sequential stream data into buffer HRESULT hr = rs.m_spStream->Read(buffer, 1000, &cbRead); if (FAILED (hr)) break; // Output buffer to file buffer[cbRead] = 0; outfile << buffer; // Test for end of data stream if (cbRead < 1000) break; } rs.CloseAll(); CoUninitialize(); return 0; }