تطبيق مستهلك بسيط
تظهر المواضيع التالية كيفية تحرير ملفات تم إنشاؤها بواسطة معالج التطبيقات MFC "و" معالج مستهلك ATL OLE DB لإنشاء مستهلك بسيط. يحتوي هذا المثال على المتطلبات التالية:
"استرداد البيانات بالمستهلك" يظهر كيفية تنفيذ التعليمات البرمجية في المستهلك الذى يقرأ كافة البيانات، صف بصف من جدول قاعدة بيانات.
"إضافة دعم إشارة مرجعية إلى مستهلك" يوضح كيف يتم إضافة دعم الإشارة المرجعية إلى مستهلك.
"إضافة دعم XML إلى العملاء" يُظهر كيفية تعديل التعليمة البرمجية للمستهلك لإخراج بيانات مجموعة الصفوف المستردة كبيانات XML.
ملاحظة
يمكنك استخدام تطبيق المستهلك الموصوف في هذا المقطع لاختبار نماذج الموفرين MyProv و Provider.
ملاحظة
لبناء تطبيق مستهلك لاختبار MyProv (نفس الموفر الذي تم وصفه في تحسين موفر بسيط للقراءة فقط)، يجب عليك تضمين دعم الإشارة المرجعية كما هو موضح في "إضافة دعم إشارة مرجعية إلى المستهلك."
ملاحظة
لبناء تطبيق مستهلك لاختبار Provider، أُترك دعم الإشارة المرجعية الموضح في "إضافة دعم إشارة مرجعية إلى مستهلك '' و تخطي إلى"إضافة دعم XML إلى مستهلك. "
استرداد بيانات بالمستهلك
لتعديل تطبيق وحدة التحكم للاستخدام في مستهلك OLE DB
في MyCons.cpp, قم بـتغيير التعليمات البرمجية الرئيسية عن طريق إدراج النص الغامق كما يلي:
// 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; }
إضافة دعم إشارة مرجعية إلى المستهلك
الإشارة المرجعية هي عمود يعرف الصفوف في الجدول بشكل فريد. عادةً ما يكون هو العمود المفتاح ، ولكنه ليس دوماً; إنه خاص بالموفر. يعرض هذا القسم كيفية إضافة دعم إشارة مرجعية. للقيام بذلك تحتاج للقيام بما يلي في فئة سجلات المستخدم:
قم بـإنشاء مثيل إشارة مرجعية. هذه كائنات من نوع CBookmark.
أُطلب عمود الإشارة المرجعية من الموفر عن طريق تعيين الخاصية DBPROP_IRowsetLocate .
قم بـإضافة إدخال الإشارة مرجعية إلى مخطط العمود باستخدام الماكرو BOOKMARK_ENTRY.
تمنحك الخطوات السابقة دعم الإشارة المرجعية و كائن الإشارة مرجعية الذي يمكن للعمل معه. يوضح مثال التعليمات البرمجية هذا الإشارة المرجعية كما يلي:
إفتح ملفاً للكتابة.
أخرج مجموعة صفوف البيانات إلى الملف من صف.
قم بـتحريك مؤشر مجموعة الصفوف إلى الإشارة المرجعية عن طريق استدعاء MoveToBookmark .
إخرج الصف ذا الإشارة المرجعية لإلحاقه إلى نهاية الملف.
ملاحظة
إذا كنت تستخدم تطبيق المستهلك لاختبار تطبيق موفر النموذج Provider أُترك دعم الإشارة المرجعية الموصوف في هذا المقطع.
لإنشاء مثيل للإشارة المرجعية
يحتاج الموصل أن يحتوي على كائن من نوع CBookmark. المعلمة nSize تحدد حجم المخزن المؤقت للإشارة المرجعية (عادةً 4 للأنظمة الأساسية 32-بت و 8 الأنظمة الأساسية 64-bit). أضف التصريح التالي لأعضاء بيانات العمود في فئة سجلات المستخدم:
////////////////////////////////////////////////////////////////////// // Products.h class CProductsAccessor { public: CBookmark<4> m_bookmark; // Add bookmark declaration LONG m_ProductID; ...
لطلب عمود الإشارة مرجعية من الموفر
أضف التعليمة البرمجية التالية في الأسلوب GetRowsetProperties في فئة سجلات المستخدم:
// 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); }
لإضافة إدخال الإشارة مرجعية إلى مخطط العمود
قم بـإضافة الإدخال التالي لمخطط العمود في فئة سجلات المستخدم:
// 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()
لاستخدام إشارة مرجعية في التعليمات البرمجية الرئيسية
في ملف MyCons.cpp من تطبيق وحدة التحكم الذي قمت بـإنشائه من قبل قم بـتغيير التعليمات البرمجية الرئيسية للقراءة كما يلي. لاستخدام الإشارات المرجعية، تحتاج التعليمات البرمجية الرئيسية لإنشاء مثيل كائن الإشارة المرجعية الخاص بها ( myBookmark); هذ إشارة مرجعية مختلفة من تلك الموجودة في الموصل ( m_bookmark).
/////////////////////////////////////////////////////////////////////// // 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; }
للحصول على مزيد من المعلومات حول الإشارات المرجعية ، راجع استخدام الإشارات المرجعية . يتم أيضاً عرض أمثلة الإشارات المرجعية في تحديث مجموعات الصفوف.
إضافة دعم XML إلى المستهلك
كما تمت مناقشته في الوصول إلى بيانات XML ، توجد طريقتان لاسترداد بيانات XML من مصدر البيانات: باستخدام CStreamRowset أو باستخدام CXMLAccessor. يستخدم هذا المثال CStreamRowset ، والذي هو أكثر فعالية ولكن يتطلب أن يكون لديك SQL Server 2000 قيد التشغيل على الكمبيوتر الذي تقوم بتنفيذ نموذج التطبيق هذا عليه.
لتعديل فئة الأمر لترث من CStreamRowset
في تطبيق العميل الذي قمت بـإنشائه من قبل قم بـتغيير تصريح CCommand الخاص بك لتحديد CStreamRowset كفئة مجموعة الصفوف كما يلي:
class CProducts : public CCommand<CAccessor<CProductsAccessor>, CStreamRowset >
لتعديل التعليمات البرمجية الرئيسية لاسترداد و إخراج بيانات XML
في ملف MyCons.cpp من تطبيق وحدة التحكم الذي قمت بـإنشائه من قبل قم بـتغيير التعليمات البرمجية الرئيسية للقراءة كما يلي.
/////////////////////////////////////////////////////////////////////// // 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; }