CRUD Operations – Updating Underlying Database

ADO.NET with C# in Hindi - BccFalna.com: TechTalks in Hindi ये Article इस वेबसाईट पर Selling हेतु उपलब्‍ध EBook ADO.NET with C# in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी रहा, तो निश्चित रूप से ये पुस्तक भी आपके लिए काफी उपयोगी साबित होगी। 

ADO.NET with C# in Hindi | Page:501 | Format: PDF

BUY NOW DOWNLOAD READ ONLINE

CRUD Operations: ExecuteReader() Method का प्रयोग हम किसी DataReader Object के साथ केवल Underlying Database पर SELECT Query Fire करने के लिए ही कर सकते हैं। जबकि यदि हमें Underlying Database में नया Record Insert करना हो, किसी Record को Delete करना हो या किसी Record के Data को Change करके Update करना हो अथवा यदि हमें अन्य Non-Query SQL Statements Execute करते हुए Table, View आदि Schema Objects Create करना हो या Permission Grant करना हो, तो हमें हमारे Command Object के ExecuteReader() Method के स्थान पर ExecuteNonQuery() Method को Use करना होता है।

ये Single Method हमारे SQL Command के आधार पर INSERT, UPDATE, DELETE व अन्य विभिन्न प्रकार के Non-Query SQL Statements को Underlying Database पर Execute करने में सक्षम है। इसलिए सभी प्रकार के Non-Query कामों को पूरा करने के लिए हमें इस Method को Use करना होता है।

तकनीकी रूप से कहें तो Non-Query SQL Statement, एक ऐसा SQL Statement होता है, जो कोई Resultset Return नहीं करता। इसलिए SELECT Statement को छोडकर अन्य कोई भी Statement एक प्रकार का Non-Query SQL Statement ही होता है और Non-Query Statement को Execute करने के लिए हमें हमारे Command Object के साथ ExecuteNonQuery() Method को Execute करना होता है।

हालांकि ये Method भी एक Integer Value Return करता है, जो इस बात को Indicate करता है कि Non-Query Statement के Execute होने की वजह से Underlying Database पर कितने Rows प्रभावित हुए हैं।

उदाहरण के लिए यदि हम Underlying Database के 10 Records को Update करने के लिए कोई SQL Command Fire करते हैं, तो इस ExecuteNonQuery() Method से Return होने वाले Integer का मान 10 होता है, क्योंकि इस Method के माध्‍यम से Execute होने वाली SQL Query द्वारा 10 Records के Data Change हो रहे हैं।

Structuring Common Task’s Library

जब हम Production Level Environment में अपना Database Application Create कर रहे होते हैं, तो हमारा ADO.NET Logic लगभग हमेंशा .NET की विभिन्न *.dll Assembly से Isolated रहता है, ताकि Code Reuse किया जाना सम्भव हो सके।

इसलिए अपने हर Program के लिए बार-बार समान Coding जैसे कि Connection Open करने के अथवा Command Object Create करने के Logic को लिखनाए कोई समझदारी वाली बात नहीं है, जबकि हम इन बार-बार Repeatedly किए जाने वाले Tasks के लिए लि[ो जाने वाले Codes को Reuse कर सकते हैं।

हम हमारे Application से सम्बंधित Common Tasks की एक ऐसी Library Create कर सकते हैं, जिनका प्रयोग हम हमारे अलग-अलग Applications में बार-बार कर सकते हैं। यानी Data Access Logics को .NET Code Library के रूप में Isolate करने का मतलब ये है कि हम जितने चाहें उतने प्रकार के Applications (Desktop Frontend, Console Based Application, Web Application, etc…) को Programming Language Independent तरीके से इन Common Codes की Library को Reference करते हुए ConnectionCommand Object को बार-बार Reuse कर सकते हैं।

परिणामस्वरूप जिस समय एक Developer उसी Common Library को Use करते हुए User Interface Design कर रहा होता है, उसी समय उसी Library का प्रयोग करते हुए कोई दूसरा Developer किसी अन्य प्रकार की Requirement को पूरा कर सकता है।

Visual Studio हमें Common Functionalities Provide करने वाले Members Define करने के लिए Class Library Create करने की सुविधा भी Provide करता है। Class Library Create करने के लिए हमें Visual Studio के FILE => New => Project Option को Click करना होता है और Display होने वाले Dialog Box में निम्न चित्रानुसार Class Library को Select करके उसका Appropriate नाम Specify करते हुए OK Button पर Click करना होता है:

CRUD Operations - Updating Underlying Database - Hindi

CRUD Operations – Updating Underlying Database – Hindi

Create होने वाली नई Class File को हम निम्नानुसार Setup कर सकते हैं, जिसमें हम हमारे Common Library Codes Specify करेंगे:

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;

namespace NWCommonFunctionalities
{
    public class NWConnectedLayerLibrary
    {

    }
}

Common Tasks की Library का उपरोक्तानुसार Structure तैयार करने के बाद हम हमारी जरूरत के अनुसार Common Functionalities को Implement करने के लिए अग्रानुसार Logics Create कर सकते हैं।

Adding Connection Logic

किसी भी Underlying Data Source के साथ Connection Open व Close करने के लिए हम दो अलग Method Create कर सकते हैं, जो कि एक Valid ConnectionString के आधार पर Underlying Data Source पर Connection को Open करता है और काम पूरा हो जाने के बाद Connection को Close करने की सुविधा Provide करता है।

चूंकि हम ये मान रहे हैं कि हम इस Library को केवल SQL Server के साथ ही Use करेंगे, इसलिए हमारा Connection Logic पूरी तरह से Hard-Coded SqlClient Codes पर ही आधारित है, जबकि विभिन्न प्रकार के Data Providers के लिए Common Code Create करने हेतु हम हमारे इस Connection Code को Modify भी कर सकते हैं।

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;

namespace NWCommonFunctionalities
{
    public class NWConnectedLayerLibrary
    {
        // This member will be used by all methods.
        private SqlConnection sqlCn = null;

        public void OpenConnection(string connectionString)
        {
            sqlCn = new SqlConnection();
            sqlCn.ConnectionString = connectionString;
            sqlCn.Open();
        }

        public void CloseConnection()
        {
            sqlCn.Close();
        }
    }
}

जैसाकि इस Code में हम देख सकते हैं कि हमने हमारी Class में SqlConnection Type का sqlCn नाम का एक Private Property Create किया है, ताकि इस Library के सभी Members इस Property के माध्‍यम से Connection Object को Common रूप से Access कर सकें।

जब हम इस Library के OpenConnection() Method को Call करते हैं, तो इस Method में Parameter के रूप में वह ConnectionString Pass करते हैं, जिसके आधार पर हमें Underlying Database पर हमारा Connection Open करना होता है।

हालांकि इस Library Code में हमने Connection Open करते समय किसी भी तरह का Exception Handling नहीं किया है, लेकिन यदि हम चाहें तो Exception Generate कर सकने वाले Codes को try…catch Block के माध्‍यम से भी Specify कर सकते हैं, ताकि Connection Related किसी भी तरह के Exception को Handle किया जा सके।

Adding Insertion Logic

किसी Record को Customers Table में Insert करना काफी आसान है, जिसके अन्तर्गत हमें किसी Insert SQL Statement को Appropriate तरीके से Format करना होता है और फिर ExecuteNonQuery() Method को Command Object के साथ Call करते हुए इस SQL Statement को Underlying Database पर Execute करना होता है।

चूंकि हम यहां केवल यही मान रहे हैं कि हमें केवल Products Table में ही नया Record Insert करना है, जबकि एक Database में एक से ज्यादा Tables हो सकते हैं और जरूरत के अनुसार एक से ज्यादा Tables में भी नया Row Insert किया जा सकता है। इस स्थिति में हमें हर Table में नया Record Insert करने के लिए एक अलग Insert Method Create करना पड सकता है, क्योंकि हर Table में Insert होने वाले Row के Columns अलग होते हैं।

public void InsertProduct(
	int ProductID, string ProductName, int SupplierID, int CategoryID, int QuantityPerUnit, 
	float UnitPrice, int UnitsInStock, int UnitsOnOrder, int ReorderLevel, int Discontinued)
    {
        // Format and execute SQL statement.
        string sql = string.Format("INSERT INTO Products
			(ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit, 
			UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued) 
		VALUES
			('{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}')", 
			ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit, 
			UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued);
            
            // Execute using our connection.
            using (SqlCommand cmd = new SqlCommand(sql, this.sqlCn))
            {
                cmd.ExecuteNonQuery();
            }
        }

जैसाकि इस Method Code द्वारा हम समझ सकते हैं कि हर Table में नया Row Insert करने के लिए हमें उस Method के Columns की Values को Parameter के रूप में इस Method में Pass करना होता है।

इसलिए यदि हमारे Database में 10 Tables हों और हम एक Library के माध्‍यम से सभी Tables में Record Insert करना चाहें, तो हर Table में Record Insert करने के लिए हमें उपरोक्तानुसार तरीके से ही एक Method Create करना होगा, जो कि किसी Particular Table में किसी Record को Insert करता है। Parameter के रूप में आने वाले विभिन्न Columns की Vales को string.Format() Method के माध्‍यम से हमने निम्नानुसार इसीलिए Format किया है:

        string sql = string.Format("INSERT INTO Products
			(ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit, 
			UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued) 
		VALUES
			('{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}')", 
			ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit, 
			UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued);

ताकि किसी भी तरह से Unauthorized तरीके से Underlying Database में नया Record Insert न किया जा सके, बल्कि Database में केवल वही Record Insert हो सके, जो इस Format को पूरी तरह से Follow करता हो। इस तरीके से नया Record INSERT करने का SQL Statement Create कर लेने के बाद Underlying Database पर इस Statement को Execute करने के लिए हमने निम्नानुसार Statement Specify किया है:

            using (SqlCommand cmd = new SqlCommand(sql, this.sqlCn))
            {
                cmd.ExecuteNonQuery();
            }

इस Statement के माध्‍यम से हमने सबसे पहले एक using Statement में SqlCommand Type का cmd नाम का Object Create किया है और इस Newly Create होने वाले Command Object के Constructor में पहले Parameter के रूप में उपरोक्त SQL Statement को Specify किया है, जबकि दूसरे Argument के रूप में Currently Opened Connection Object को Specify किया है।

परिणामस्वरूप यदि बिना किसी परेशानी के Command Object Create हो जाता है, तो अन्तिम Statement के रूप में ExecuteNonQuery() Method Execute होता है और sql Variable में जो SQL Statement Specified होता है, वह SQL Statement, Underlying Database पर Execute हो जाता है। फलस्वरूप Underlying Database में एक नया Product Add हो जाता है।

यदि हम Products नाम की एक नई Class Create करें, जिसका Structure निम्नानुसार हो:

    class Products
    {
        public int ProductID {get; set;}
        public string ProductName { get; set; }
        public int SupplierID { get; set; }
        public int CategoryID { get; set; }
        public int QuantityPerUnit { get; set; }
        public float UnitPrice { get; set; }
        public int UnitsInStock { get; set; }
        public int UnitsOnOrder { get; set; }
        public int ReorderLevel { get; set; }
        public int Discontinued { get; set; }
    }

तो जैसाकि हम समझ सकते हैं कि इस Class का Structure और हमारी Products नाम की Table का Structure एक समान है। यानी हमारी Products Table में जो Columns हैं, उन सभी Columns से Associated एक Property उपरोक्त Defined Products Class में भी है।

इसलिए जिस तरह से पिछले InsertProduct() Method में हमने Products Table के विभिन्न Columns को Parameter के रूप में Pass किया है, ठीक उसी तरह से हम Products Class का Object भी Parameter की तरह Pass कर सकते हैं, जिसे Accept करने के लिए हमें हमारे InsertProduct() Method को निम्नानुसार Modify करना पडेगा:

public void InsertProduct( Products p )
    {
        // Format and execute SQL statement.
        string sql = string.Format("INSERT INTO Products
			(ProductID, ProductName, SupplierID, CategoryID, QuantityPerUnit, 
			UnitPrice, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued) 
		VALUES
			('{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}')", 
			p.ProductID, p.ProductName, p.SupplierID, p.CategoryID, p.QuantityPerUnit, 
			p.UnitPrice, p.UnitsInStock, p.UnitsOnOrder, p.ReorderLevel, p.Discontinued);
            
            // Execute using our connection.
            using (SqlCommand cmd = new SqlCommand(sql, this.sqlCn))
            {
                cmd.ExecuteNonQuery();
            }
        }

यानी यदि हम चाहें तो अपनी Database की सभी Tables का एक Alternative Class Create कर सकते हैं, जो कि किसी Specific Table को हमारे Frontend Application में एक Type की तरह Represent करेगा।

परिणामस्वरूप Underlying Database के Data को हम ठीक उसी तरह से Access व Manipulate करने के लिए Design कर सकते हैं, जैसे कि वह Data Underlying Database से Access होने के बजा; Current Application के Types से ही Access हो रहा हो।

ऐसी Class Define करना जो कि किसी Relational Database के Records को Represent करे, Data Access Library Create करने का एक Common तरीका है और इसी तरीके के आधार पर Microsoft द्वारा ADO.NET Entity Framework को Design किया गया है।

Entity Framework एक ऐसा API है, जिसे ADO.NET की Upper Layer के रूप में Design किया गया है। इस API के माध्‍यम से जब हम Database Application Create करते हैं, तो Underlying Database की सभी Tables, Frontend Application में एक Strongly Typed Class के रूप में Automatically Create हो जाती हैं।

परिणामस्वरूप हम हमारे Frontend Application में तो इन Strongly Typed Classes के Objects के साथ Interact करते हैं, जबकि इनके साथ किया गया हर Interaction Underlying Database पर Automatically Apply हो जाता है। इसी तरह से इन Strongly Typed Objects को Access करने पर जो Data हमें प्राप्त होता है, वह Data वास्तव में Underlying Database से Retrieve होता है।

हालांकि इस पुस्तक में हम Entity Framework के विष; में कोई Discussion नहीं करेंगे, लेकिन Entity Framework वास्तव में Object Oriented तरीके से Underlying Relational Database को Access व Manipulate करने का एक सरल व Efficient तरीका Provide करता है। साथ ही Entity Framework पूरी तरह से ADO.NET पर आधारित है, इसलिए ADO.NET की Working को Proper तरीके से समझे बिना Entity Framework को भी ठीक से नहीं समझा जा सकता।

Adding Deletion Logic

जिस तरह से हम नया Record Insert करने के लिए Method Create करते हैं, उसी तरह से हम किसी Record को Delete करने के लिए भी हर Table के लिए एक अलग Method Create कर सकते हैं। लेकिन क्योंकि किसी Object को Delete करते समय Database की Relationship के माध्‍यम से Define की गई Integrity प्रभावित हो सकती है, इसलिए Row Deletion के Code को हमेंशा try…catch Block के बीच Enclose किया जाना जरूरी होता है।

        public void DeleteProduct(int id)
        {
            // Get ID of car to delete, then do so.
            string sql = string.Format("DELETE FROM Products WHERE ProductID = '{0}'", id);
            using (SqlCommand cmd = new SqlCommand(sql, this.sqlCn))
            {
                try
                {
                    cmd.ExecuteNonQuery();
                }
                catch (SqlException ex)
                {
                    Exception error = new Exception("Sorry! That product is on order!", ex);
                    throw error;
                }
            }
        }

जैसाकि इस Code द्वारा हम समझ सकते हैं कि इस Method में हमने Parameter के रूप में एक ID Pass किया है, जो कि उस Product का ID है, जिसे Delete करना है। लेकिन क्योंकि जिस Product को Delete किया जा रहा है, वह किसी Order में Exist हो सकता है और जो Product किसी Order में Exist हो, उसे Delete नहीं किया जा सकता। इसलिए इस स्थिति में एक Exception Trigger होना चाहिए। इस Integrity को Handle करने के लिए ही इस Method में Deletion के Logic को एक try…catch Block में Enclose किया गया है।

Adding Update Logic

जब हमें किसी Table के Record को Update करना होता है, तब सबसे पहले हमें इस बात को त; करना होता है कि हम User को Table के किन Data को Change करने की Permission देना चाहते हैं।

उदाहरण के लिए हम कभी भी किसी Product के ID Field को Change करने की Permission किसी भी User को नहीं दे सकते क्योंकि इस ID Field से अन्य Records Relationship के माध्‍यम से आपस में जुडे रहते हैं। अत: यदि Primary Key को Modify कर दिया जाए, तो Data Integrity व Consistency प्रभावित हो सकती है।

जब हम Data Update के लिए Logic Create करना चाहते हैं, तो सबसे बेहतर तरीका तो यही होता है कि Table के हर उस Column को Update करने के लिए एक अलग Method Create किया जाए, जिसे हम, User द्वारा Modify हो सकने के लिए Authorize करना चाहते हैं और इस तरह का Method हम कुछ निम्नानुसार Create कर सकते हैं:

        public void UpdateProductName(int id, string newProductName)
        {
            // Get ID of car to modify and new pet name.
            string sql = string.Format( "UPDATE Products SET ProductName = '{0}' WHERE ProductID = '{1}'", newProductName, id);
            using(SqlCommand cmd = new SqlCommand(sql, this.sqlCn))
            {
                cmd.ExecuteNonQuery();
            }
        }

जैसाकि इस Method द्वारा हम समझ सकते हैं कि ये Method पहले Parameter के रूप में उस Product का ID Accept करता है, जिसे Update करना है जबकि दूसरे Parameter के रूप में उस Update किए जाने वाले Product के Name Field की Value को Accept करता है, जिसे Method की Body में Specify किए गए UPDATE SQL Statement में Parameter की तरह Use किया गया है।

हालांकि इस Manner का प्रयोग करके हम बहुत ही बेहतर तरीके से उन Columns के Data को Change करने के लिए User को हर Table के हर Column के लिए एक Unique Method Provide कर सकते हैं, लेकिन इस तरीके को Use करने की एक परेशानी ये भी है कि यदि किसी Table में 100 Columns हों, जिनमें से 90 Columns के Data को User Change कर सकता हो, तो 90 Columns को Modify करने के लिए हमें 90 Methods Create करने होंगे। इस स्थिति से बचने के लिए हम एक Single Method Create कर सकते हैं, जो कि किसी Record के सभी Columns को एक ही बार में Modify करने में सक्षम हो।

Adding Selection Logic

जैसाकि हमने DataReader Object को Use करते समय जाना था कि हम DataReader Object का प्रयोग करके Read-Only, Forward-Only Server Side Cursor के माध्‍यम से जरूरत के आधार पर Underlying Database से Records का Selection कर सकते हैं और Underlying Database से Return होने वाले Rows को Read() Method का प्रयोग करके One-by-One Process कर सकते हैं।

चूंकि Records के Selection का ये एक अच्छा तरीका है, इसलिए हम एक ऐसा Method Create कर सकते हैं, जो एक List Object के रूप हमारे Select किए गए Records को Return करे, ताकि हम उन Records को अपनी जरूरत के अनुसार Use कर सकें।

        public List<Products> GetAllProductsAsList()
        {
            // This will hold the records.
            List<Products> prod = new List<Products>();

            // Prep command object.
            string sql = "SELECT * FROM Products";
            using (SqlCommand cmd = new SqlCommand(sql, this.sqlCn))
            {
                SqlDataReader dr = cmd.ExecuteReader();
                while (dr.Read())
                {
                    prod.Add(new Products
                    {
                        ProductID = (int)dr["ProductID"], 
                        ProductName = (string)dr["ProductName"], 
                        SupplierID = (int)dr["SupplierID"],
                        CategoryID = (int)dr["CategoryID"], 
                        QuantityPerUnit = (int)dr["QuantityPerUnit"], 
                        UnitPrice = (float)dr["UnitPrice"], 
                        UnitsInStock = (short)dr["UnitsInStock"], 
                        UnitsOnOrder = (short)dr["UnitsOnOrder"], 
                        ReorderLevel = (short)dr["ReorderLevel"],
                        Discontinued = (short)dr["Discontinued"]
                    });
                }
                dr.Close();
            }
            return prod;
        }

चूंकि इस Code में हमने एक Generic Method Create किया है, इसलिए ये Method उसी स्थिति में Normal तरीके से काम करेगा, जबकि हम निम्नानुसार Generic Namespace को अपनी Library File में Include करें:

using System.Collections.Generic;

साथ ही इस Code में हमने Products नाम की Class Type के Objects का Array Retrieve करने के लिए निम्नानुसार Products नाम की एक Class भी Crate की है, यदि हम इस Class को Define न करें, तो ये Method, Products Type के Objects की List Return नहीं करेगा:

    public class Products
    {
        public int ProductID { get; set; }
        public string ProductName { get; set; }
        public int SupplierID { get; set; }
        public int CategoryID { get; set; }
        public int QuantityPerUnit { get; set; }
        public float UnitPrice { get; set; }
        public int UnitsInStock { get; set; }
        public int UnitsOnOrder { get; set; }
        public int ReorderLevel { get; set; }
        public int Discontinued { get; set; }
    }

जब ये Code Run होता है तो सबसे पहले prod नाम का List Type का एक Generic Object Create करता है, जो कि Products Type के Objects के एक Array को Represent करता है। जब इस Code का using Statement Run होता है, तो Execute होने वाला Command Object dr नाम का एक DataReader Object Return करता है, जिसके हर Record को Read() Method के माध्‍यम से Access किया जाता है और हर Record के हर Column की Value को prod नाम के List Type के Object में एक Element की तरह Place कर दिया जाता है। इस काम को निम्न Code द्वारा Perform किया जाता है:

                    prod.Add(new Products
                    {
                        ProductID = (int)dr["ProductID"], 
                        ProductName = (string)dr["ProductName"], 
                        SupplierID = (int)dr["SupplierID"],
                        CategoryID = (int)dr["CategoryID"], 
                        QuantityPerUnit = (int)dr["QuantityPerUnit"], 
                        UnitPrice = (float)dr["UnitPrice"], 
                        UnitsInStock = (short)dr["UnitsInStock"], 
                        UnitsOnOrder = (short)dr["UnitsOnOrder"], 
                        ReorderLevel = (short)dr["ReorderLevel"],
                        Discontinued = (short)dr["Discontinued"]
                    });

अन्त में जब सारे Records prod नाम के Object में एक Unique Array Element की तरह Store हो जाते हैं, उसके बाद prod नाम के List Object को Return कर दिया जाता है, जिसे Calling Method जिस तरह से चाहे उस तरह से Access करते हुए Products Table के सभी Records को Access कर सकता है।

उपरोक्त तरीके को Use करने के स्थान पर हम एक और तरीका Use कर सकते हैं, जिसमें Records का एक List Type का Object Return करने के स्थान पर हम System.Data.DataTable Type का Object Return कर सकते हैं, जो कि एक प्रकार से Virtual Table की तरह Underlying Database के Table के सभी Records को In-Memory Represent करता है।

हालांकि DataTable Object वास्तव में ADO.NET के Disconnected Layer का Part है, जिसके बारे में हम आगे जानेंगे। फिर भी हमारी Current जरूरत के सन्दर्भ में हम इसे यहां पर Use कर रहे हैं, जहां DataTable Class Type हमारी Table के Data को एक In-Memory Table के रूप में Represent कर रहा है।

DataTable Class, Data को Internally RowsColumns के एक Collection के रूप esa Represent करता है। इसलिए यदि हम चाहें तो इस Collection को Programmatically भी Fill कर सकते हैं, जिसे Fill करने के लिए हमें Load() Method को Use करना होता है। ये Method Automatically इन Collection को DataReader Object में Stored Data के माध्‍यम से Fill कर देता है। जैसे:

        public DataTable GetAllProductsAsDataTable()
        {
            // This will hold the records.
            DataTable dtProducts= new DataTable();

            // Prepare command object.
            string sql = "SELECT * FROM Products";

            using (SqlCommand cmdProduct = new SqlCommand(sql, this.sqlCn))
            {
                SqlDataReader drProduct = cmdProduct.ExecuteReader();

                // Fill the DataTable with data from the reader and clean up.
                dtProducts.Load(drProduct);
                drProduct.Close();
            }
            return dtProducts;
        }

जब हम इस Method को Call करते हैं, तो सबसे पहले ये Method dtProducts नाम का एक DataTable Object Create करता है। फिर using Statement के माध्‍यम से cmdProduct नाम का एक Command Object Create होता है, जो कि Products Table के सभी Records को drProduct Object में Store कर देता है। जिसे अब निम्नानुसार Statement द्वारा dtProducts Object में Load कर दिया जाता है:

dtProducts.Load(drProduct);

परिणामस्वरूप जब ये Statement Execute होता है, तो DataReader Object में Underlying Database जो भी Records Retrieve होते हैं, वे सभी Records एक In-Memory Table के रूप में dtProducts नाम के DataTable Object में Fill हो जाते हैं, जिसे इस Method द्वारा Calling Method को Return कर दिया जाता है। जहां Calling Method इस Return होने वाले DataTable Object को जिस तरह से चाहे उस तरह से Access कर सकता है।

Parameterized Command Object

String Formatted SQL Queries, Frontend Database से External Data Source पर Pass होता है। इस SQL Query String में न केवल Essential Command Keywords व Syntactical Elements होते हैं, बल्कि हर Query द्वारा Return होने वाले Resultset को Limit करने के लिए Data Values भी होते हैं, जिन्हें WHERE Clause के साथ Condition या Criteria के रूप में Specify किया जाता है।

String Formatted SQL Queries Create करना लगभग सभी प्रकार के Data Sources से Data Access व Manipulate करने के लिए Use किया जाने वाला एक जरूरी Step है। लेकिन String Format के रूप में SQL Query को Use करना न केवल काफी असुविधाजनक होता है, बल्कि Risky भी होता है। क्योंकि इस तरह की SQL Queries Use करने पर SQL Injection Attack होने की सम्भावना रहती है।

SQL Server Provider में Parameters System.Data.SqlClient.SqlParameter Class के रूप में प्राप्त होते हैं। इस Class के Objects Create करके उन्हें SqlCommand Object के साथ Add करके हम Parameterized Queries Define कर सकते हैं। जबकि यदि हमें ODBC या OLEDB को Use करते हुए Parameterized Query Create करनी हो, तो हमें System.Data.OleDb.OleDbParameter या System.Data.Odbc.OdbcParameter Class के Object Create करके OleDbCommand या OdbcCommand Object में Add करना होता है।

C# DataReader Object - Disconnected Layer
SQL Injection Example - Parameterized Queries

ADO.NET with C# in Hindi - BccFalna.com: TechTalks in Hindi ये Article इस वेबसाईट पर Selling हेतु उपलब्‍ध EBook ADO.NET with C# in Hindi से लिया गया है। इसलिए यदि ये Article आपके लिए उपयोगी रहा, तो निश्चित रूप से ये पुस्तक भी आपके लिए काफी उपयोगी साबित होगी। 

ADO.NET with C# in Hindi | Page:501 | Format: PDF

BUY NOW DOWNLOAD READ ONLINE

Download All Hindi EBooks

सभी हिन्दी EBooks C, C++, Java, C#, ASP.NET, Oracle, Data Structure, VB6, PHP, HTML5, JavaScript, jQuery, WordPress, etc... के DOWNLOAD LINKS प्राप्‍त करें, अपने EMail पर।

Register करके Login करें। इस Popup से छुटकारा पाएें।