इस लेख में हम ADO.NET एप्लीकेशन किस प्रकार डेटाबेस के साथ इंटरेक्शन करता है और डेटाबेस के डाटा को एक्सेस करने के लिए कनेक्ट करता है इस संबंध में जानेंगे।
दो प्रकार के वेब एप्लिकेशन
ASP.NET वेब एप्लीकेशन 2 टियर एप्लीकेशन हो सकता है अथवा 3 टियर एप्लीकेशन हो सकता है। 2 टियर अप्लीकेशन के अंतर्गत क्लाइंट सर्वर मॉडल होता है। क्लाइंट सर्वर से किसी रिसोर्स के लिए रिक्वेस्ट करता है। ततपश्चात सर्वर उस रिक्वेस्ट को प्रोसेस करके रिस्पांस दे देता है। 3 टियर एप्लिकेशन के अंतर्गत क्लाइंट और सर्वर के अतिरिक्त एक बिजनेस लेयर भी होता है। बिजनेस लेयर एप्लिकेशन के बिजनेस लॉजिक से संबंधित होता है और यह क्लाइंट और सर्वर के बीच में मध्यस्थ का कार्य करता है। बिजनेस लेयर गत्यात्मक/डायनेमिक होता है, इसका कारण यह है कि जहाँ क्लाइंट प्रेजेंटेशन लेयर को रीप्रजेंट करता है वही दूसरी ओर सर्वर डाटाबेस लेयर को। वेबसर्वर डेटाबेस के साथ इंटरेक्शन करके क्लाइंट के पास डाटा भेज देता है लेकिन यह किस प्रकार का डाटा भेजेगा, यह इस बात पर निर्भर करता है कि बिजनेस लॉजिक और रिक्वायरमेंट क्या है। बिजनेस रिक्वायरमेंट अक्सर परिवर्तनशील volatile और dynamic होता है। चूंकि बिजनेस की जरूरतें परिवर्तित होती रहती हैं, अतः बिजनेस लॉजिक लेयर सबसे अधिक परिवर्तनशील होता है।
माइक्रोसॉफ्ट डेटाबेस टेक्नोलॉजी
डेटाबेस से एप्लिकेशन के इंटरेक्शन करने के लिए माइक्रोसॉफ्ट ने समय के साथ-साथ कई तरह की नई-नई डाटाबेस तकनीकों का विकास किया। माइक्रोसॉफ्ट द्वारा डेटाबेस टेक्नोलॉजी का विकास कई रूपों में हुआ जैसे DAO, RDO, ADO, ADO.NET, OLEDB इत्यादि।
विभिन्न डाटा मॉडल
DAO Data Access Object
RDO Remote Data Object
ADO ActiveX Data Object
ODBC Open Database Connectivity
OLEDB Object Linking and Embedding Database
DAO के अंतर्गत कई प्रकार के फंक्शनैलिटी और परफॉर्मेंस के issues थे। DAO डाटा मॉडल का उपयोग लोकल डाटा के लिए किया जाता था, इसके विपरीत RDO का उद्भव रिमोट डाटा को एक्सेस करने के लिए किया गया। RDO का उपयोग करके किसी भी रिमोट मशीन से डाटा को एक्सेस करके एप्लीकेशन दिखा सकता था लेकिन इसमें भी कुछ-कुछ परफॉर्ममेंस और फंक्शनैलिटी संबंधी दिक्कतें थी।
ADO का विकास क्लाइंट सर्वर आर्किटेक्चर के अनुसार किया गया। यह RDO से ज्यादा बेहतर था। अतः यह मार्केट में बहुत जल्द प्रचलित हो गया लेकिन इसमें भी कुछ कमियां थी, जैसे ADO के अंतर्गत डेटाबेस के एक सिंगल टेबल के डाटा को स्टोर करने के लिए Recordset ऑब्जेक्ट को यूज किया जाता है। ADO के अंतर्गत Recordset इन मेमोरी डाटा को रिप्रेजेंट करता है इसके विपरीत ADO.NET के अंतर्गत इन मेमोरी डाटा के लिए Dataset का उपयोग किया जाता है। इन मेमोरी डाटा से अभिप्राय क्लाइंट मशीन के मेमोरी में डाटाबेस के tables को स्टोर करने से है। Dataset का उपयोग एक या एक से अधिक डेटाबेस tables और उनके अंतरसंबंध को स्टोर करने के लिए किया जा सकता है।
साथ ही, ADO के अंतर्गत कनेक्टेड डाटा मॉडल का उपयोग किया जाता है।
कनेक्टेड डाटा मॉडल का अभिप्राय यह है कि जब क्लाइंट एप्लिकेशन डाटाबेस के साथ कनेक्शन स्थापित कर लेता है तो यह कनेक्शन लगातार बना रहता है जब तक डाटा को प्रोसेस किया जा रहा है। इस कारण कनेक्शन सतत रूप से open रहता है जो ज्यादा resource को यूज करता है और सिक्युरिटी सम्बंधित बाधाएं भी उत्पन्न होने की सम्भावना रहती है।
इसके विपरीत ADO.NET के अंतर्गत डिस्कनेक्टेड डाटा बेस मॉडल का उपयोग किया जाता है। डिस्कनेक्टेड डाटाबेस मॉडल के अंतर्गत एक या एक से अधिक डेटाबेस tables को Dataset के अंतर्गत रख लिया जाता है और ततपश्चात डाटाबेस से कनेक्शन को तोड़ दिया जाता है। बाद में, सारे काम Dataset को यूज करते हुए किया जाता है। इससे नेटवर्क ट्रैफिक जाम नहीं होता है।
ADO कनेक्टेड डाटाबेस मॉडल के अंतर्गत कुछ खामियां हैं जैसे सिक्योरिटी संबंधी खामियां और नेटवर्क ट्रैफिक संबंधी खामियां। कनेक्टेड डाटाबेस मॉडल के अंतर्गत जब एप्लीकेशन डाटाबेस के साथ कनेक्शन कर लेता है तो वह कनेक्शन सतत रूप से ओपन रहता है जब तक कि डाटाबेस के ऊपर DML आपरेशन्स जैसे insert, update, delete का प्रोसेस होता रहता है इसके कारण सिक्योरिटी सुप्रदा होता है इसी तरह लगातार कनेक्शन ओपन नेटवर्क ट्रैफिक जाम होने के चांस बने रहते हैं। ADO मॉडल के अंतर्गत यह खामिया भी है कि यदि यूजर्स की संख्या 100 से ज्यादा हो तो उसकी परफॉर्मेंस में प्रॉब्लम आती है।
ऊपर की सब समस्याओं को ध्यान में रखते हुए बाद में माइक्रोसॉफ्ट ने ADO.NET टेक्नोलॉजी का विकास किया। ADO.NET की विशेषता है कि यह XML लैंगुएज को सपोर्ट करता है। जब डाटा को एक मशीन से दूसरे मशीन पर XML डाटा के रूप में ट्रांसफर करना हो तो उस हालत में ADO.NET का उपयोग किया जा सकता है जबकि ADO तकनीक XML के रूप में डाटा ट्रांसफर को सपोर्ट नहीं करता है। यह फ़ायरवॉल से भी असुविधा उत्पन्न नहीं करता है। इस तरह ADO की खामियों को दूर करने में मददगार साबित हुआ है।
कनेक्टेड डाटा मॉडल के ऑब्जेक्ट्स
कनेक्टेड डाटा मॉडल के अंतर्गत डाटा सोर्स के साथ एप्लीकेशन कनेक्शन स्थापित करता है। कनेक्शन का अभिप्राय यह है कि डाटा सोर्स के साथ एप्लीकेशन सुरक्षित तरीके से आपस में संबंध स्थापित करता है। इस सुरक्षित संबंध को ही कनेक्शन कहते हैं। कनेक्शन स्थापित करने के लिए डाटा सोर्स से संबंधित अनेक तरह की जानकारियां जैसे सर्वर का नाम, डेटाबेस का नाम, यूजरनेम और पासवर्ड इत्यादि कई प्रकार की सुरक्षा संबंधी जानकारियां कनेक्शन ऑब्जेक्ट के भीतर इनकैप्सूलेट कर दी जाती है। कनेक्शन स्ट्रिंग इसी से सम्बंधित है। अतः कनेक्टेड डाटा मॉडल एक सुरक्षित तरीका है, जिस तरीके से डाटा सोर्स के साथ संबंध स्थापित कर डाटा को यूज किया जाता है। यूज करने से अभिप्राय डाटा को select, insert, अपडेट डिलीट करने इत्यादि से है।
कलेक्टेड डाटा मॉडल के अंतर्गत कनेक्शन Connection ऑब्जेक्ट के अलावा और भी कई अन्य प्रकार के ऑब्जेक्ट होते हैं जैसे Command, Parameters कलेक्शन, DataReader डाटारीडर इत्यादि।
जब तक कनेक्शन स्थापित होता है विभिन्न प्रकार के ऑब्जेक्ट के उपयोग Data Source के साथ किया जाता है।
कनेक्शन स्ट्रिंग एक स्ट्रिंग होता है जिसमें डाटा सोर्स के संबंध में सूचना दी हुई होती है और यह भी दिया होता है कि किस तरीके से हम उस डाटा सोर्स के साथ कनेक्शन स्थापित कर सकते हैं। कनेक्शन स्ट्रिंग के भीतर ड्राइवर का नाम सर्वर का नाम डाटाबेस का नाम और सिक्योरिटी संबंधित जानकारियां जैसे यूजरनेम और पासवर्ड भी दिया होता है। कनेक्शन स्ट्रिंग का उपयोग कोड में डाटाबेस से कनेक्शन स्थापित करने के लिए किया जाता है। कनेक्शन स्ट्रिंग के भीतर कई सारे पारामीटर होते हैं जैसे डाटा सोर्स, सरवर, इनिशियल कैटलॉग, ट्रस्टेड कनेक्शन, इनिशियल फाइल नेम, कनेक्शन टाइमआउट इत्यादि।
Connected Data Architecture Objects
- DataReader
- Connection
- Command
- Parameter collection
- Transaction
- DataAdapter
डाटा प्रोवाइडर
कलेक्टेड डाटा मॉडल से संबंधित एक और भी महत्वपूर्ण जानकारी है जिसे डाटा प्रोवाइडर कहते हैं। डाटा प्रोवाइडर अलग अलग डेटाबेस के लिए अलग अलग होता है। उदाहरण के लिए, एसक्यूएल सर्वर ओरेकल या अन्य किसी भी डाटाबेस के लिए डाटा प्रोवाइडर अलग होता है। डाटा प्रोवाइडर क्या है? ऊपर जो कनेक्शन, कमांड या अन्य जो भी ऑब्जेक्ट्स ऊपर मॉडल में बात किया है यह सभी डेटाबेस के अनुसार अलग-अलग होते हैं जैसे एसक्यूएल सर्वर के लिए Connection ऑब्जेक्ट, कमांड ऑब्जेक्ट है जिन्हें SqlConnection, SqlCommand कहते हैं। इसी तरह, Oracle डाटाबेस के लिए OracleConnection, OracleCommand ऑब्जेक्ट्स हैं।
DataProvider for SQLServer
System.Data.SqlClient namespace has classes like SqlConnection, SqlCommand, SqlDataAdapter, SqlDataReader
DataProvider for OLEDB
System.Data.Oledb namespace has classes like OledbConnection, OledbCommand, OledbDataAdapter, OledbDataReader
DataProvider for ODBC
System.Data.Odbc namespace has classes like OdbcConnection, OdbcCommand, OdbcDataAdapter, OdbcDataReader
DataProvider for Oracle
System.Data.OracleClient namespace has classes like OracleConnection, OracleCommand, OracleDataAdapter, OracleDataReader
Disconnected Data Architecture
- DataTable collection
- DataTable
- DataColumn
- DataRow
- Constraint collection
- DataRelation collection
डाटा एडाप्टर कनेक्टड डाटा बेस मॉडल और डिस्कनेक्ट डाटा बेस मॉडल इन दोनों के बीच में ब्रिज का काम करता है।
System.Data namespace contains Dataset class. It's a generic class and not related to any particular kind of database.
Connection कनेक्शन ऑब्जेक्ट का उपयोग डेटाबेस के साथ कनेक्शन स्थापित करने के लिए किया जाता है। कनेक्शन ऑब्जेक्ट के कुछ प्रॉपर्टी है जिनकी सहायता से डेटाबेस सरवर डेटाबेस का नाम यूजर का नाम पासवर्ड इत्यादि के संबंध में जानकारी एकत्र की जा सकती है।
कनेक्शन ऑब्जेक्ट के निम्न प्रॉपर्टीज है
ConnectionString
ConnectionTimeOut
Database
State
Except Connection String, all the other properties are read only.
कनेक्शन ऑब्जेक्ट के निम्न methods है
BeginTransaction()
CreateCommand()
ChangeDatabase()
Open()
Close()
Command object in details:-
Command represents queries and stored procedures. Depending upon the database, we have following commands.
SqlCommand
OracleCommand
OledbCommand
Command ऑब्जेक्ट का उपयोग किसी कमांड को एक्सक्यूट करने के लिए किया जाता है अलग-अलग तरह के डाटा प्रोवाइडर के लिए अलग-अलग तरह के Command उपलब्ध है। उदाहरण के लिए माइक्रोसॉफ्ट एसक्यूएल सर्वर SQLServer के लिए SqlCommand, ओरेकल डाटाबेस सर्वर के लिए OracleCommand और अन्य विभिन्न प्रकार के डाटासोर्स जैसे एक्सेल फ़ाइल से कनेक्शन स्थापित करने के लिए OledbCommand है।
Command प्रॉपर्टीज निम्नलिखित हैं
CommandText
CommandTimeOut
CommandType
Connection
Parameters
Transaction
CommandText का अर्थ कमांड से संबंधित क्वेरी या स्टोर्ड प्रोसीजर के नाम से ही है। क्वेरी के पूरे टेक्स्ट अथवा अगर स्टोर्ड प्रोसीजर है तो स्टोर्ड प्रोसीजर का नाम CommandText का मान होता हैं।CommandType का मान enumerated वैल्यू होता है जो क्वेरी या स्टोर्ड प्रोसीजर होता है। CommandTimeOut यह बताता है कि कितने समय के भीतर कोई कमांड रन हो जाना चाहिए। अगर उस समय अवधि के भीतर कमांड अर्थात क्वेरी या स्टोर्ड प्रोसीजर रन नहीं होता है तो उसे कैंसिल कर दिया जाएगा। Command object बिना कनेक्शन ऑब्जेक्ट के अर्थहीन है क्योंकि कमांड अगर क्वेरी या स्टोर्ड प्रोसीजर है तो कमांड को रन करने के लिए यह भी मालूम होना चाहिए कि यह कमांड या स्टोर्ड प्रोसीजर या क्वेरी किस सर्वर के, किस डेटाबेस से जुड़ा हुआ है। इन सब चीजों की जानकारी कनेक्शन ऑब्जेक्ट में होती है, अतः कमांड ऑब्जेक्ट का एक प्रॉपर्टी कनेक्शन है। जब कमांड ऑब्जेक्ट की प्रॉपर्टी कनेक्शन यूज किया जाता है तब यह दोनों ऑब्जेक्ट आपस में अंतरसंबंधित हो जाते हैं और पूरी तरह उनका आपस में अर्थ बन जाता है। अतः कमांड ऑब्जेक्ट बिना कनेक्शन ऑब्जेक्ट के अधूरा है। CommandText का मान SQL क्वेरी स्ट्रिंग दिया जाता है अथवा स्टोर्ड प्रोसीजर stored procedure का नाम दिया जाता है। SQL क्वेरी अथवा स्टोर्ड प्रोसीजर को एग्जीक्यूट करने के लिए CommandText को सम्बंधित नाम assign किया जाता है।
Data Access models
Local database DAO
Remote database RDO
ADO Recordset, Connected data model
ADO.NET Dataset, Disconnected data model
OLEDB
ODBC
Connection object in details
किसी भी डेटाबेस प्रोग्रामिंग के अंतर्गत कनेक्शन शब्द का अर्थ समझना जरूरी है। asp.net के अंतर्गत किसी डेटाबेस से डाटा को एक्सेस करने के लिए वेब सर्वर को उस डाटाबेस सर्वर के साथ कनेक्शन स्थापित करना होता है। जब उस डाटाबेस सर्वर के साथ वेब सर्वर का कनेक्शन स्थापित हो जाता है तब उस डेटाबेस के किसी टेबल से डाटा को fetch किया जा सकता है। डेटाबेस प्रोग्रामिंग के अंतर्गत कनेक्शन का क्या निहितार्थ है? इस बात को समझने के लिए हम एक रूपक का उदाहरण लेंगे।
मान लीजिए किसी नदी के जल को आपके घर तक पहुंचाना हो तो उसके लिए क्या उपाय किया जाएगा। उसके लिए हमें उस नदी से घर तक कनेक्शन स्थापित करना होगा। यहाँ कनेक्शन का अभिप्राय पाइप लाइन बिछाने से है, पाइप लाइन बिछाने के लिए हमें खर्च करना होगा साथ ही, हमें पानी को खींचने के लिए मोटर पंप की भी जरूरत होगी। इस तरह हम देखते हैं जलधारा को जल स्रोत से लक्ष्य तक पहुंचाने के लिए कई तरह के खर्च करने पड़ते हैं।
ठीक इसी तरह की बात डेटाबेस कनेक्शन के साथ भी है। हम जानते हैं कि अलग-अलग तरह के डेटाबेस सर्वर होते हैं जैसे माइक्रोसॉफ्ट एसक्यूएल सर्वर, ओरेकल सर्वर, MySQL इत्यादि। प्रत्येक डेटाबेस सर्वर की प्रकृति अलग-अलग है। अतः उनसे डाटा को fetch करने के लिए अर्थात वेब सर्वर तक डाटा को पहुंचाने के लिए खास खास तरह की तकनीक का प्रयोग करना होता है। अतः डाटा प्राप्त fetch करने के लिए जिन तकनीक का उपयोग किया जाता है वही उसका खर्च cost है।
अब हम देखते हैं कि वेब सर्वर को डाटा सर्वर के साथ कनेक्शन स्थापित करने के लिए क्या क्या साधन चाहिए। कनेक्शन बनाने के लिए सर्वप्रथम वेब सर्वर को उस डेटाबेस सर्वर के बारे में कोड में बताना पड़ता है। साथ ही, यह भी बताना पड़ता है कि डाटाबेस सर्वर के किस डाटाबेस के साथ कनेक्शन को जोड़ना है। और इसके अलावा, अलग-अलग तरह के डाटाबेस सर्वर के होने कारण हमें डेटाबेस प्रोवाइडर की भी जरूरत पड़ती है जो किसी खास डेटाबेस सर्वर के साथ जुड़कर डाटा को fetch कर पाता है। उदाहरण के लिए नल सरोवर माइक्रोसॉफ्ट एसक्यूएल सर्वर के साथ कनेक्शन स्थापित करने के लिए अलग तरह के प्रोवाइडर की जरूरत पड़ती है जबकि ओरेकल के लिए किसी और प्रकार के प्रोवाइडर की जरूरत पड़ती है। प्रोवाइडर मूल रूप से सॉफ्टवेयर है और यह सॉफ्टवेयर कंपनियां बनाती है।
कनेक्शन स्थापित करने के लिए कई तरह की तकनीक है जैसे कि कनेक्शन स्ट्रिंग।
कनेक्शन स्ट्रिंग टेक्निक के अंतर्गत किसी डेटाबेस सर्वर के साथ कनेक्शन स्थापित करने के लिए कई सारे एट्रिब्यूट को एक स्ट्रिंग वेरिएबल के भीतर डिफाइन करना होता है जो इस प्रकार है। सबसे पहले तो डाटा सोर्स या सर्वर का नाम देना पड़ता है जिसके साथ कनेक्शन स्थापित करना है दूसरा उस सर्वर के किसी खास डेटाबेस का भी नाम देना पड़ता है इसके अलावा यूजरनेम और पासवर्ड को भी कनेक्शन स्ट्रिंग के भीतर दिया जाता है। विंडोज authentication की स्थिति में यूजरनेम और पासवर्ड नहीं दिया जाता है। साथ ही, डेटाबेस प्रोवाइडर का नाम भी देना अनिवार्य है।
बेव एप्लीकेशन के अंतर्गत कनेक्शन स्ट्रिंग का उपयोग एएसपीएक्स फाइल के अंतर्गत किया जाता है। इसके अलावा हम इसका उपयोग वेबकॉन्फ़िग फाइल के भीतर भी कर सकते हैं। जब एएसपीएक्स फाइल के अंतर्गत कनेक्शन स्ट्रिंग का उपयोग किया जाता है तो इस वेरिएबल का स्कोप application-level होता है जबकि एएसपीएक्स फ़ाइल के अंतर्गत कनेक्शन स्ट्रिंग का उपयोग करने पर उसका स्कोप केवल उसी पेज तक होता है।
कनेक्शन के कंसेप्ट को अलग-अलग तकनीक के द्वारा इंप्लीमेंट किया जा सकता है। माइक्रोसॉफ्ट में इसको ADO ActiveX Data Object एडीओ टेक्नोलॉजी, ADO.NET टेक्नोलॉजी और अन्य तकनीक में इंप्लीमेंट किया गया है।
कनेक्शन ऑब्जेक्ट के कुछ मेथड्स और प्रोपर्टीज होते हैं जिनके द्वारा किसी डेटाबेस सर्वर के साथ कनेक्शन स्थापित किया जाता है।
Properties of Command
CommandText
CommandType
CommandTimeOut
Connection
Parameters
Transaction
Methods of Command
ExecuteNonQuery() जब insert, update या delete क्वेरी होता है तो इस मेथड का प्रयोग किया जाता है। दूसरे शब्दों में, एक्शन क्वेरी के लिए यह मेथड यूज किया जाता है।
ExecuteScalar() इस मेथड का यूज तब किया जाता है जब क्वेरी एक सिंगल वैल्यू वापस करता है।
ExecuteReader() जब SELECT क्वेरी का यूज किया जाता है तब इस मेथड का यूज किया जाता है।
Cancel() इस मेथड का यूज किसी कमांड को कैंसिल करने के लिए किया जाता है।
CreateParameter()
जब किसी डेटाबेस टेबल से रिकॉर्ड क्वेरी करते हैं तब कई बार हमें उस टेबल को फिल्टर करना होता है और फिल्टर करने के लिए हम क्वेरी में व्हेयर WHERE क्लॉज का यूज करते हैं। WHERE क्लोज के expression में यूजर कांस्टेंट वैल्यू देते हैं, जिस वैल्यू के आधार पर फिल्टर किया जाता है और इस कांस्टेंट वैल्यू को हम डायनॉमिकली देने के लिए पैरामीटर के रूप में प्रस्तुत करते हैं। किसी क्वेरी में पैरामीटर होने का अर्थ है कि यूजर उस क्वेरी में फिल्टर का यूज कर रहा है। फिल्टर क्वेरी को हम पैरामीटराइज्ड क्वेरी भी कहते हैं। पैरामीटराइज्ड क्वेरी के अंतर्गत यूजर डायनामिकली पैरामीटर की वैल्यू प्रदान करता है और उस वैल्यू के आधार पर टेबल को फिल्टर करके रिकॉर्ड्स को प्रस्तुत होता है। आमतौर पर, पैरामीटर को फॉर्म के भीतर एक फील्ड के रूप में दर्शाया जाता है और उस फील्ड/कंट्रोल के भीतर यूजर इनपुट करता है। ADO और ADO.NET के अंतर्गत पैरामीटर एक ऑब्जेक्ट होता है और ऑब्जेक्ट में पैरामीटर की वैल्यू इनकैप्सूलेट की जाती है। जैसा कि हमने देखा कि पैरामीटर एक ऑब्जेक्ट होता है होता है इसके प्रॉपर्टी ओर मेथड भी होंगे इसके दो महत्वपूर्ण प्रॉपर्टीज है Name और Value अब Name के द्वारा पैरामीटर का नाम दिया जाता है जबकि Value के द्वारा उस पैरामीटर की वैल्यू दी जाती है। उदाहरण के लिए
Dim Conn as New SqlConnection("data source=.; database=Company; integrated security=SSPI")
Dim param as New SqlParameter
param.Name = "@Age"
param.Value = 18
Dim cmd as New SqlCommand("SELECT * FROM tblEmpl WHERE age = @Age", conn)
cmd.Parameters.Add(param)
किसी भी query-string के भीतर पैरामीटर को दर्शाने के लिए उसके पहले एट द रेट @ सिंबल का यूज किया जाता है। उदाहरण के लिए,
Prepare ()
ResetCommandTimeOut()
DataReader is object is a read only forward only stream of data. It holds a single record of data in memory at a time. It is fast in operation.
Properties of DataReader
Field Count
HasRows
IsClosed
Item
RecordsAffected return -1
© अजीत कुमार, सर्वाधिकार सुरक्षित।
इस आलेख को उद्धृत करते हुए इस लेख के लिंक का भी विवरण दें। इस आलेख को कॉपीराइट सूचना के साथ यथावत साझा करने की अनुमति है। कृपया इसे ऐसे स्थान पर साझा न करें जहाँ इसे देखने के लिए शुल्क देना पडे।
No comments:
Post a Comment