GridView Control: जैसाकि हमने पिछले Discussion में समझा है कि Database पर Connection जितनी ज्यादा देर तक Open रहता है, Database की Connection Pooling Performance उतनी ही ज्यादा प्रभावित होती है। इसलिए इस स्थिति में हमें एक ऐसे Disconnected Cache Object की जरूरत होती है, जो Database से Generate होने वाले हर Record को Represent करे और इस जरूरत को IDataRecords Collection द्वारा पूरा किया जाता है।
इस IDataRecords Type का Collection उस स्थिति में काफी उपयोगी साबित होता है, जबकि हम इस Collected Resultset को किसी GUI Data-Binding Control में Pass करना चाहते हैं या किसी अन्य प्रकार की Data Processing करना चाहते हैं, जिसमें हमें सभी Records को एक साथ Access व Manipulate करना होता है।
ये Collection उस समय भी काफी उपयोगी साबित होता है, जब हम Database से Returned Resultset को जितना ज्यादा तेजी से सम्भव हो सके, उतना ज्यादा तेजी से Read करना होता है। इसीलिए हम DataReader Object को Use करते हैं। लेकिन Resultset पर हमें जो Processing Perform करनी है, उसमें यदि काफी ज्यादा समय लगने वाला हो, तो उस पूरे समय के दौरान Database पर Connection Open रहता है, जिससे Database की Performance प्रभावित होती है।
अत: DataReader का प्रयोग करके हम इस प्रकार के Resultset को तो Frontend में Process कर सकते हैं, लेकिन हमें एक ऐसे तरीके की भी जरूरत होती है कि जब DataReader में सारा Result पूरी तरह से Fill हो जाए, तो Connection को Close किया जा सके, ताकि उसे किसी अन्य User की Request को पूरा करने के लिए Reuse किया जा सके, जबकि DataReader Object द्वारा Slow Network Speed में भी Frontend में Resultset Serve होता रहे।
यानी जिस दौरान DataReader Underlying Database से Returned सभी Records से Fill हो चुका होता है, उसी दौरान Frontend को भी Resultset Transfer हो रहा होता है लेकिन जैसे ही DataReader पूरी तरह से Fill हो जाता है, Underlying Database के साथ Established Connection को Close कर दिया जाना चाहिए, ताकि जब तक Frontend Application, DataReader Object से Data को Network की Slow Speed के कारण धीरे&धीरे Retrieve कर रहा हो, उस दौरान Database पर Connection Open न रहे।
इसलिए हमें DataReader के Resultset के सारे Records को तेजी से Iterate करते हुए Further Processing के लिए Store करने हेतु एक बेहतर तरीके की जरूरत होती है, ताकि Underlying Connection को जितना जल्दी हो सके उतना जल्दी Close किया जा सके।
इस जरूरत को पूरा करने के लिए SqlDataReader Class हमें GetEnumerator नाम का एक Method Provide करता है जिसका प्रयोग करके हम foreach Construct को Use कर सकते हैं। foreach Construct में Enumerator किसी Collection में Exist विभिन्न Objects को Sequentially Return करता है।
यानी यदि हम इस Method को अपने SqlDataReader Object के साथ Use करें, तो ये Enumerator हमें DataReader Object में Stored विभिन्न Records को One-by-One DbDataRecords Object के रूप में Return करता है।
इस प्रक्रिया को ज्यादा बेहतर तरीके से समझने के लिए हम अग्रानुसार एक Practical GUI Example Program Create कर सकते हैं, जिसमें Form पर एक DataGrid Control Exist है, जिसमें हम DataReader में Stored विभिन्न Records को Display करना चाहते हैं।
चूंकि हम एक Window Based GUI Program Create करना चाहते हैं, इसलिए सबसे पहले हमें Visual Studio के FILE Menu => New => Project… Option को Click करना होता है। इस Menu Option को Click करते ही हमारे समाने निम्नानुसार एक “New Project” Dialog Box Display होता है:
उपरोक्त चित्र में दर्शाए अनुसार “Visual C#” Template के अन्तर्गत दिखाई देने वाले विभिन्न प्रकार के Projects में से हमें “Windows Forms Application” को Select करके उसका Name, Location आदि Specify करना होता है और सारी Information Specify करने के बाद हमें OK Button पर Click करना होता है।
जैसे ही हम OK Button पर Click करते हैं, एक नया Windows Form Project Create हो जाता है और हमारे सामने निम्न चित्रानुसार एक Form Display होने लगता है:
जैसाकि हम देख सकते हैं कि ये Form Exactly Visual Basic के समान ही दिखाई दे रहा है और Visual Basic के समान ही हम इस Form की भी विभिन्न जरूरी Properties को Set कर सकते हैं, जिनमें से Text Property व Name Property सबसे महत्वपूर्ण Properties होती हैं।
क्योंकि Text Property में हम जो String Specify करते हैं, वह String इस Form के Title Bar पर Display होती है, जबकि Name Property में Specify किया गया String, Application के Code Window में Form को Identify करने के लिए Use किया जाता है। इन दोनों Properties के अलावा और भी बहुत सारी Properties होती हैं, जिन्हें हम हमारी जरूरत के अनुसार Design Time या Runtime में Set कर सकते हैं।
चूंकि हम एक DataGrid Control में Backend Database से आने वाले Data को Display करना चाहते हैं, इसलिए अब हमें हमारी जरूरत के अनुसार इस Form को Design करना होता है और विभिन्न प्रकार के सभी जरूरी Controls को Form पर Place करने के साथ ही उनकी सभी जरूरी Properties को Set करना होता है। अपनी जरूरत के अनुसार हम हमारे Form को कुछ निम्नानुसार Design कर सकते हैं, जिस पर एक DataGrid Control व दो Command Buttons Exist हैं:
चूंकि “Windows Forms Application” पूरी तरह से Visual Basic की तरह ही काम करता है, अन्तर केवल इतना है कि हमें Visual Basic के स्थान पर C# Programming Language के Code Syntaxes को Use करना होता है, इसलिए सबसे पहले हम इस Form पर स्थित Exit Button की Coding लिखेंगे, ताकि हम हमारे Application के इस Form से Exit कर सकें और Exit Button का Code लिखने के लिए हमें इस Form पर दिखाई दे रहे “Exit” Button को Double Click करना होता है।
जैसे ही हम इस Button पर Double Click करते हैं, हमारे समाने निम्नानुसार Code Window Open हो जाता है, जिसमें कुछ Code पहले से लि[ो होते हैं। जहां पर हमारा Cursor Blink करता है, वहीं पर हमें हमारे “Exit” Button के लिए Code लिखना होता है। यानी हमारे Exit Button का Code Procedure कुछ निम्नानुसार होता है:
private void cmdExit_Click(object sender, EventArgs e) { this.Close(); }
इस Code Procedure को हम Event Handler भी कह सकते हैं। इस Event Handler में cmdExit हमारे Exit Button का नाम है, जिसे हमने Visual Studio के Properties Window में Set किया है, जबकि Click वह Event है, जिसके Fire होने पर ये Procedure Execute होगा। यानी हम जैसे ही इस Form पर दिखाई देने वाले “Exit” Button पर Click करेंगे, उपरोक्त Code Execute होगा और Current Form को Close कर देगा।
ठीक इसी तरह से हमें हमारे “Populate” Button की Coding लिखने के लिए भी इस Button को Double Click करना होता है। जैसे ही हम इस Button को Double Click करते हैं, हम फिर से Visual Studio के Code Window में पहुंच जाते हैं, जहां निम्नानुसार एक नया Event Handler Create हो जाता है:
private void btnPopulate_Click(object sender, EventArgs e) { }
इस Event Handler में cmdPopulate हमारे Form पर दिखाई देने वाले Populate Button का नाम है, जिसे हमने Visual Studio के Properties Window में Set किया है, जबकि Click वह Event है, जिसके Fire होने पर ये Procedure Execute होगा। यानी हम जैसे ही इस Form पर दिखाई देने वाले “Populate” Button पर Click करेंगे, उपरोक्त Event Handler Execute होगा और उसमें लि[ो गए सारे Codes अपना काम करेंगे।
इस Populate Button के Event Handler में ही हमें वह Code लिखना होता है, जो DataReader Object में Stored सभी Records को One-by-One Form पर स्थित DataGrid Control में Fill करता हैं। DataGrid Control में Underlying Data Source से Return होने वाले Data को Fill करने के लिए हम इस Event Handler को निम्नानुसार Specify कर सकते हैं:
private void btnPopulate_Click(object sender, EventArgs e) { SqlConnectionStringBuilder sqlConBuilder = new SqlConnectionStringBuilder( "Data Source=.\\SQLSERVEREXPRESS;Initial Catalog=pubs;Integrated Security = true"); SqlConnection testConnection = new SqlConnection(sqlConBuilder.ToString()); SqlCommand testCommand = new SqlCommand ("SELECT * FROM authors", testConnection); using (testConnection) { testConnection.Open(); SqlDataReader allAuthors = testCommand.ExecuteReader(CommandBehavior.CloseConnection); ArrayList dbRecordsHolder = new ArrayList(); if (allAuthors.HasRows) { foreach (DbDataRecord record in allAuthors) { dbRecordsHolder.Add(record); // dbRecordsHolder is an ArrayList } } dgAllRecords.DataSource = dbRecordsHolder; } // testConnection.Dispose() called automatically. }
जैसाकि हम इस Event Handler को देखकर समझ सकते हैं कि इसमें लिखा गया Code लगभग पिछले Program के Code जैसा ही है। अन्तर केवल इस Event Handler में Specify किए गए if Statement Block के Code में ही है।
जब हम हमारे Form पर दिखाई देने वाले “Populate” Button पर Click करते हैं, तब ये Event Handler Execute होता है। Execute होते ही सबसे पहले ये Event Handler Underlying Data Source के साथ Connection Open() करता है और फिर उस Open किए गए Connection पर ExecuteReader() Method के माध्यम से Command Object में Specified SQL Query Fire करता है।
परिणामस्वरूप pubs नाम के Database की authors नाम की Table के सारे Records Return होते हैं, जिन्हें SqlDataReader Type के allAuthors नाम के एक Object में Store किया जाता है।
फिर dbRecordsHolder नाम का एक ArrayList Type का Object Create किया जाता है, जो कि एक प्रकार का Collection Object होता है।
फिर एक if Statement में इस बात को Check किया जाता है कि allAuthors नाम के DataReader Object में कोई Record Exist है या नहीं।
चूंकि authors Table में Records हैं, इसलिए Connection के Normal तरीके से Open होने व Command के Normal तरीके से Execute होने की स्थिति में इस Object में सभी Authors की Information Rows के रूप में Stored होती है। परिणामस्वरूप if Condition True होने की वजह से Program Control if Statement Block में Enter करता है।
चूंकि DataReader Object में Stored सभी Records को जब foreach के माध्यम से Enumerate किया जाता है, तब ये Object सभी Records को One-by-One एक DbDataRecords Type के Object के रूप में Return करता है। इस Return होने वाले DbDataRecord Type के Object को dbRecordsHolder नाम के ArrayList Object में Store करने के लिए Add() Method का प्रयोग किया जाता है।
परिणामस्वरूप Underlying Data Source से Returned सभी Records, जो कि DataReader Object में Stored होते हैं, One-by-One dbRecordsHolder में Store हो जाते हैं, जिसे अन्त में निम्न Statement का प्रयोग करके हमारे Form पर स्थिति DataGrid Control की DataSource Property में Specify करते हैं:
dgAllRecords.DataSource = dbRecordsHolder;
इस Statement के Execute होते ही हमें हमारा Resultant Form कुछ निम्नानुसार दिखाई देने लगता है:
यहां एक और ध्यान रखने वाली बात ये है कि हालांकि जब हम Windows Forms Application Create करते हैं, तब हमें ArrayList जैसा Object Create करने की जरूरत पडती है, जिसे DataGrid Control की DataSource Property में Assign करके DataReader Object के Data को Access किया जाता है। लेकिन जब हम ASP.NET Application Create करते हैं, तब हम DataGrid Control को सीधे ही DataReader Object Assign कर सकते हैं। यानी हमें अलग से ArrayList Collection Type का Object Create करने की जरूरत नहीं रहती।
इस प्रकार से यदि हम हमारे पिछले Windows Forms Based GUI Database Application Program के पूरे Source Code को Specify करें, तो ये Code कुछ निम्नानुसार होगा:
using System; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Collections; using System.Data.Common; using System.Data.SqlClient; namespace DBGUIApplication { public partial class frmDataGrid : Form { public frmDataGrid() { InitializeComponent(); } private void cmdExit_Click(object sender, EventArgs e) { this.Close(); } private void btnPopulate_Click(object sender, EventArgs e) { SqlConnectionStringBuilder sqlConBuilder = new SqlConnectionStringBuilder( "Data Source=.\\SQLSERVEREXPRESS;Initial Catalog=pubs;Integrated Security = true"); SqlConnection testConnection = new SqlConnection(sqlConBuilder.ToString()); SqlCommand testCommand = new SqlCommand ("SELECT * FROM authors", testConnection); using (testConnection) { testConnection.Open(); SqlDataReader allAuthors = testCommand.ExecuteReader(CommandBehavior.CloseConnection); ArrayList dbRecordsHolder = new ArrayList(); if (allAuthors.HasRows) { foreach (DbDataRecord record in allAuthors) { dbRecordsHolder.Add(record); // dbRecordsHolder is an ArrayList } } dgAllRecords.DataSource = dbRecordsHolder; } // testConnection.Dispose() called automatically. } } }
जब हम उपरोक्तानुसार Window Form Create करते हैं, तब एक बात हमें और ध्यान रखनी होती है कि Visual Studio सभी जरूरी Namespaces को Windows Forms के Code Window में Embed नहीं करता। इसलिए जब हम उपरोक्त Program Create करते हैं, तब हमें निम्नानुसार तीन Namespaces को Manually Specify करना जरूरी होता है:
using System.Collections;
using System.Data.Common;
using System.Data.SqlClient;
जहां पहला Namespace Specify न करने पर हम ArrayList Type का dbRecordsHolder Object Create नहीं कर सकते। जबकि दूसरा Namespace Specify न करने पर हम DbDataRecord Type का record Object Create नहीं कर सकते और तीसरा Namespace Specify न करने पर हम SQL Server Database पर Connection, ConnectionString व Command जैसे Objects Create नहीं कर सकते, जो कि Underlying Database Connection Open करने व Data Retrieve करने के लिए जिम्मेदार होते हैं।
साथ ही हमने इस Program में Dispose() Method को भी Use नहीं किया है, क्योंकि हमने हमारे Codes को using Block में लिखा है, जो कि सभी Unmanaged Resources को स्वयं ही अपने स्तर पर Collect करता रहता है, क्योंकि Dispose() Method को Connection Object के लिए Internally Call किया जाता है।
इसलिए जब उपरोक्त Program Run होता है तब हमारे DataReader Object का सारा Data ArrayList Object में Store हो जाता है, जो कि Underlying Database से पूरी तरह से Disconnected है। इसलिए जब हम DataReader के Data को DataGridView से Bind कर रहे होते हैं, तो वास्तव में हम हमारे Database से Disconnect होते हैं और हमारा Data वास्तव में ArrayList Type के dbRecordsHolder Object से आ रहा होता है।
इस तरीके का सबसे बडा फायदा यही है कि एक बार इस प्रकार से DataGrid Control में सारा Data Load हो जाने के बाद यानी सारा Data ArrayList Object में Store हो जाने के बाद हमें हमारे SqlConnection को Open रखना जरूरी नहीं होता, जबकि हमारा Frontend User Interface, Slow Network की वजह से DataReader के Data को ArrayList Collection के माध्यम से धीमी गति से DataGrid Control में Load कर रहा हो सकता है। क्योंकि हमारे सारे Data की एक Copy हमारे पास एक ArrayList Collection के रूप में उपलब्ध रहता है।
उपरोक्तानुसार तरीके से Program Create करके हम SqlConnection को जितना हो सके उतना कम समय के लिए Open रखते हैं। यानी हमारा Connection केवल तभी तक Open रहता है, जब तक कि Underlying DataSource से आने वाला Data, ArrayList Object में पूरी तरह से Load नहीं हो जाता। परिणामस्वरूप हमें काफी ज्यादा बेहतर Connection Pooling Performance प्राप्त हो जाता है।
DataGridView Control में जो Records दिखाई देते हैं, यदि हम उन Records को Edit करने की कोशिश करें, तो हम उन्हें Edit नहीं कर सकते। ये Control Data को केवल Read-Only Format में ही Display करता है क्योंकि ये Disconnected ArrayList Object से Populate हुआ है और Disconnected Object में यदि कोई Change किया जाए, तो उसका Effect Underlying Data Source पर नहीं पडता।
ये Article इस वेबसाईट पर Selling हेतु उपलब्ध EBook ADO.NET with C# in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी रहा, तो निश्चित रूप से ये पुस्तक भी आपके लिए काफी उपयोगी साबित होगी।
ADO.NET with C# in Hindi | Page:501 | Format: PDF