Database Schema Query: हालांकि उपरोक्त Form Normal तरीके से काम करता है, लेकिन इसकी एक समस्या है और वह समस्या ये है कि यदि हम उपरोक्त Form पर स्थित दोनों Buttons में से किसी भी Button को बार-बार Click करें, तो DataGridView Control में बार-बार समान Records Add होते जाते हैं।
परिणामस्वरूप यदि हम “Fill Titles” Button को 10 बार Click करें, तो DataGridView में हर Record 10 बार दिखाई देगा, जो कि नहीं होना चाहिए। इस प्रक्रिया को रोकने के लिए हमें इस बात को समझना होगा कि आिखर ऐसा क्यों होता है। चलिए, समझने की कोशिश करते हैं।
जब DataAdapter किसी पहले से Filled DataSet Object को Fill करता है, तो उसके पास इस बात को Identify करने का कोई तरीका नहीं होता कि जिस DataSet Object को वह Fill कर रहा है, वह पहले से ही Filled है, क्योंकि DataSet Object में Fill होने वाले Data के साथ कोई Primary Key Exist नहीं होता।
यानी DataSet Object में Underlying Data Source से आने वाले DataTables के Schema की कोई जानकारी नहीं है। इसलिए यदि हम चाहते हैं कि इन Buttons को बार-बार Click करने पर भी DataSet Object की DataTables में केवल एक ही बार Data Fill हो, तो हमें हमारे DataTables का Schema Create करना जरूरी होता है।
हालांकि यदि हम चाहें तो इस Schema को Manually भी Create कर सकते हैं, लेकिन हमें ऐसा करने की जरूरत नहीं है। बल्कि हम DataSource की Query कर सकते हैं और उस Queried Data से Schema को Fill कर सकते हैं। इसे समझने के लिए हम फिर से एक नया Windows Forms Application Project Create करेंगे तथा दिखाई देने वाले Form को निम्नानुसार Design करेंगे-

इस Form पर एक WebBrowser Control है जबकि “Fill Schema” व “Fill Data” Text वाले दो Button Controls हैं, जो कि WebBrowser Control में DataSet के Data को XML Format में Fill करने का काम करते हैं।
इस Application में हमने DataGridView Control को इसलिए Use नहीं किया है, क्योंकि DataGridView Control, XML Data को Display करने में सक्षम नहीं है, जबकि Underlying Data Source से DataTables की जो Schema Information, Frontend Application को Return होती है, वह XML Format में ही होती है।
अत: क्योंकि WebBrowser Control किसी भी तरह के Markup को Render करने में सक्षम होता है, इसलिए हम Entire DataSet Object को XML Format में WebBrowser Control में Directly Load कर सकते हैं।
Form Design करने के बाद फिर से हमें एक DataSet Object Declare करना होता है और उसे Memory Allocate करना होता है, जिसके लिए हम Form के Code View में जाते हैं और Pre-Generated Code को निम्नानुसार तरीके से Modify करते हैं:
using System; using System.Data; using System.Data.SqlClient; using System.Data.Common; using System.Windows.Forms; namespace AccessingDBSchema { public partial class frmAccessingDBSchema : Form { private DataSet ds4DataNSchema; public frmAccessingDBSchema() { InitializeComponent(); ds4DataNSchema = new DataSet(); } } }
फिर से Design View में जाकर “Fill Data” Button को Double Click करते हैं, ताकि उसके लिए Automatically एक Click Event Handler Create हो जाए और इस Click Event Handler को निम्नानुसार Define करते हैं:
private void btnFillData_Click(object sender, EventArgs e) { string connectionString = "Data Source=.\\SQLSERVEREXPRESS;Initial Catalog=pubs;Integrated Security=True"; using (SqlConnection conn = new SqlConnection(connectionString)) { SqlCommand comPubs = new SqlCommand("SELECT * FROM publishers; SELECT * FROM titles", conPubs); SqlDataAdapter daPubs = new SqlDataAdapter(comPubs); daPubs.Fill(ds4DataNSchema); } DisplayOutput(); }
जैसाकि हम समझ सकते हैं कि उपरोक्त Code में और पिछले Program के Form पर स्थित Button Control के Code में कोई ज्यादा अन्तर नहीं है। इस Code में लि[ो गए Code में जो सबसे मुख्य अन्तर Command Object में SQL Query Specify करने तथा Fill() Method को Use करने में ही है। क्योंकि Command Object में हमने दो SQL Queries को एक Single Statement के रूप में निम्नानुसार Specify किया है:
SqlCommand comPubs = new SqlCommand
(“SELECT * FROM publishers; SELECT * FROM titles“, conPubs);
जबकि Fill() Method को निम्नानुसार DataSet Object के रूप में केवल एक Single Parameter Pass करते हुए Specify किया है:
daPubs.Fill(ds4DataNSchema);
इसी तरह से फिर से Design View में जाकर “Fill Schema” Button को Double Click करके उसके लिए Click Event Handler को Generate करना होता है और इस Event Handler में हमें निम्नानुसार Code लिखना होता है:
private void btnFillSchema_Click(object sender, EventArgs e) { string connectionString = "Data Source=.\\SQLSERVEREXPRESS;Initial Catalog=pubs;Integrated Security=True"; using (SqlConnection conPubs = new SqlConnection(connectionString)) { SqlCommand comPubs = new SqlCommand("SELECT * FROM publishers; SELECT * FROM titles", conPubs); SqlDataAdapter daPubs = new SqlDataAdapter(comPubs); daPubs.FillSchema(ds4DataNSchema, SchemaType.Source); } DisplayOutput(); }
“Fill Schema” Button के लिए लि[ो गए उपरोक्त Code व “Fill Data” Button के लिए लि[ो गए पिछले Code में केवल Fill() Method को Use करने के तरीके का ही अन्तर है। क्योंकि पिछले Code में जहां DataSet Object को Underlying DataSource से Return होने वाले Data से Fill किया गया था, वहीं इस Code में DataSet Object को Underlying DataSource से Return होने वाले Resultset के Schema से Fill किया गया है और इस जरूरत को पूरा करने के लिए Fill() Method के स्थान पर FillSchema() Method को निम्नानुसार तरीके से Use किया गया है:
daPubs.FillSchema(ds4DataNSchema, SchemaType.Source);
जहां इस Method में Specified पहला Parameter उस DataSet Object को Specify कर रहा है, जिसे Fill करना है, जबकि दूसरे Argument के रूप में Schema के Type के रूप में SchemaType.Source मान को Specify किया गया है।
SchemaType.Source मान Specify करने के कारण Underlying DataSource से जिस तरह का Schema Related Data Return होता है, उस Data को Exactly उसी तरह से बिना किसी तरह का Transformation किए हुए ज्यों का त्यों DataSet Object में Fill कर दिया जाता है।
जैसाकि हम उपरोक्त दोनों ही Event Handlers के Code में देख सकते हैं, कि दोनों ही Event Handlers में DisplayOutput() नाम का एक Method Call किया गया है। ये Method DataSet Object के Content को XML Format Source के रूप में WebBrowser Control में Display करने का काम करता है और इस Method को निम्नानुसार Define किया जा सकता है:
private void DisplayOutput() { ds4DataNSchema.WriteXml(Application.StartupPath + "\\ds4DataNSchema.xml", XmlWriteMode.WriteSchema); wbOutput.Navigate(Application.StartupPath + "\\ds4DataNSchema.xml"); }
Form पर दिखाई देने वाले किसी भी Button को Click करने पर जब ये Code Run होता है, तो सबसे पहले ये Method हमारे DataSet Object के लिए WriteXml() Method को Call करता है। ये Method पहले Parameter के रूप में Specified Application.StartupPath यानी जहां पर हमारी Project File की Executable Saved है, (..\bin\Debug\) पर “ds4DataNSchema.xml” नाम की एक नई XML File Create करता है और उस XML File में DataSet Object में Currently जो भी Content होता है, उस Content को उसके Schema Information यानी .XSD के साथ Write कर देता है क्योंकि दूसरे Parameter के रूप में हमने XmlWriteMode.WriteSchema Constant Value Pass किया है।
जबकि यदि हम इसके स्थान पर XmlWriteMode.IgnoreSchema मान Use करते, तो Create होने वाली XML File में DataSet Object के Content यानी Data की Information तो XML Format में Store होती, लेकिन उसकी Schema Information Store नहीं होती।
फिर अगले Statement द्वारा इस Create होने वाली XML File के Path को WebBrowser Control की Navigate Property में Specify किया है, जिसकी वजह से XML File का सारा Content हमें हमारे Form के WebBrowser Control में दिखाई देने लगता है।
इस प्रकार से यदि हम हमारे Current Windows Form के सारे Codes को एक साथ Specify करें, तो हमारा Code कुछ निम्नानुसार होगा:
using System; using System.Data; using System.Data.SqlClient; using System.Data.Common; using System.Windows.Forms; namespace AccessingDBSchema { public partial class frmAccessingDBSchema : Form { private DataSet ds4DataNSchema; public frmAccessingDBSchema() { InitializeComponent(); ds4DataNSchema = new DataSet(); } private void btnFillData_Click(object sender, EventArgs e) { string connectionString = "Data Source=.\\SQLSERVEREXPRESS;Initial Catalog=pubs;Integrated Security=True"; using (SqlConnection conPubs = new SqlConnection(connectionString)) { SqlCommand comPubs = new SqlCommand("SELECT * FROM publishers; SELECT * FROM titles", conPubs); SqlDataAdapter daPubs = new SqlDataAdapter(comPubs); daPubs.Fill(ds4DataNSchema); } DisplayOutput(); } private void DisplayOutput() { ds4DataNSchema.WriteXml(Application.StartupPath + "\\ds4DataNSchema.xml", XmlWriteMode.IgnoreSchema); wbOutput.Navigate(Application.StartupPath + "\\ds4DataNSchema.xml"); } private void btnFillSchema_Click(object sender, EventArgs e) { string connectionString = "Data Source=.\\SQLSERVEREXPRESS;Initial Catalog=pubs;Integrated Security=True"; using (SqlConnection conPubs = new SqlConnection(connectionString)) { SqlCommand comPubs = new SqlCommand("SELECT * FROM publishers; SELECT * FROM titles", conPubs); SqlDataAdapter daPubs = new SqlDataAdapter(comPubs); daPubs.FillSchema(ds4DataNSchema, SchemaType.Source); } DisplayOutput(); } } }
अब जब हम इस Application को Run करते हैं और Form पर दिखाई देने वाले दोनों Buttons में से सबसे पहले “Fill Schema” Button को Click करते हैं, तो इस Button को Click करते ही Underlying Data Source से Retrieve होने वाले Data का Schema Retrieve होता है। परिणामस्वरूप अब हम चाहे जितनी बार भी “Fill Data” Button को Click करें, DataSet में सभी DataTables केवल एक ही बार Add होती हैं। जैसे:

लेकिन यदि हम इस Form को Close करके फिर से Run करें और इस बार “Fill Schema” Button को Click करने से पहले ही “Fill Data” Button को Click करें, तो हम जितनी बार भी इस Button को Click करेंगे, उतनी ही बार DataSet Object की सभी DataTables हमारे WebBrowser Control में Add होती जाती हैं, क्योंकि इस बार हमने हमारे DataSet के Schema को Add नहीं किया है। इसलिए इस बार जब हम हमारे Program के Output को देखते हैं, तो ये हमें कुछ निम्नानुसार दिखाई देता है:

यानी जब हम Underlying Data Source से आने वाले Resultset को Hold करने वाले DataSet में Data के Schema Definition को Load नहीं करते, तभी DataSet के Data का Repetition होता है।
हालांकि हम उपरोक्त तरीके का प्रयोग करके DataSet Object में Filled Data को Repeated Form में Fill होने से रोक सकते हैं। लेकिन जब हम Professional Database Application Develop करते हैं, तब ये तरीका Use नहीं किया जा सकता।
क्योंकि सामान्यत: किसी भी Real-World Application के Records की संख्या काफी ज्यादा हो सकती है और जब Underlying Database की Access की जाने वाली Table में Records की संख्या काफी ज्यादा हो, अथवा यदि हम ASP.NET का प्रयोग करते हुए Database Driven Web Application Develop कर रहे हों, तो इस प्रकार के Slow Speed व कम Bandwidth वाले Network पर बहुत सारे Data को बार-बार DataSet Object में Load करना Database पर काफी Negative Effect डालता है।
क्योंकि सामान्यत: लगभग सभी Database Applications GUI Based होते हैं और एक GUI Based Frontend के किसी DataGridView जैसे Control को DataSet Object में Stored बहुत सारे Data से Load करने पर Frontend User Interface की Performance को भी काफी ज्यादा प्रभावित करता है।
साथ ही जब बहुत ज्यादा Records की Processing हो रही होती है, तब इस प्रकार के GUI Form पर User किसी DataGridView जैसे Control के माध्यम से Data में कोई Modification करता है, तो उस Modification को Underlying Database में Save करने में भी काफी ज्यादा समय लग सकता है, जो कि Underlying Database पर और भी ज्यादा प्रभाव डालता है।
यानी यदि हम उपरोक्त तरीके को Use करते हुए अपने DataSet Object को Refresh करते हैं, तो कई तरह की परेशानियों का सामना करना पडता है। साथ ही हमारे Application की Performance भी काफी ज्यादा प्रभावित होती है। इसलिए इस तरीके को केवल तभी Use किया जाता है जबकि हमें बहुत कम Records के साथ Processing करनी होती है।
ये Article इस वेबसाईट पर Selling हेतु उपलब्ध EBook ADO.NET with C# in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी रहा, तो निश्चित रूप से ये पुस्तक भी आपके लिए काफी उपयोगी साबित होगी।
ADO.NET with C# in Hindi | Page:501 | Format: PDF