تطبيق مستهلك بسيط

تظهر المواضيع التالية كيفية تحرير ملفات تم إنشاؤها بواسطة معالج التطبيقات 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;
    }
    

راجع أيضًا:

المبادئ

إنشاء مستهلك OLE DB باستخدام معالج