www.binaryintellect.net Open in urlscan Pro
199.233.254.89  Public Scan

URL: https://www.binaryintellect.net/articles/1a7ab1ca-979c-4177-abcb-1445fcc66f60.aspx
Submission: On July 23 via manual from PL — Scanned from PL

Form analysis 1 forms found in the DOM

POST ./1a7ab1ca-979c-4177-abcb-1445fcc66f60.aspx

<form method="post" action="./1a7ab1ca-979c-4177-abcb-1445fcc66f60.aspx" id="aspnetForm">
  <div class="aspNetHidden">
    <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
      value="/wEPDwUKMTY4Nzg3ODA2NGQYBAU7Y3RsMDAkQ29udGVudFBsYWNlSG9sZGVyMSRncmlkUG9wdWxhckZyb21DYXRlZ29yeSRHcmlkVmlldzMPZ2QFO2N0bDAwJENvbnRlbnRQbGFjZUhvbGRlcjEkZ3JpZFBvcHVsYXJGcm9tQ2F0ZWdvcnkkR3JpZFZpZXcyDzwrAAwBCAIBZAU7Y3RsMDAkQ29udGVudFBsYWNlSG9sZGVyMSRncmlkUG9wdWxhckZyb21DYXRlZ29yeSRHcmlkVmlldzEPZ2QFI2N0bDAwJENvbnRlbnRQbGFjZUhvbGRlcjEkZ3JpZExpbmtzDzwrAAwBCGZkkhn9SU1OFqoimLlst9TrPVEzAZHRP7LWvwAczGeeScA=">
  </div>
  <div class="aspNetHidden">
    <input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="14C6E5A8">
  </div>
  <div id="container">
    <div id="header">
      <div id="slogan" title="BinaryIntellect Knowledge Base | .NET &amp; Web Development KB By Bipin Joshi"><a href="/default.aspx"><img src="/images/logos/SloganBlue.png"></a></div>
      <div id="logo" title="BinaryIntellect Knowledge Base | .NET &amp; Web Development KB By Bipin Joshi"><a href="/default.aspx"><img src="/images/logos/techbloglogo.png"></a></div>
    </div>
    <div id="menubar">
      <table id="ctl00_topmenubar_DataList1" cellspacing="0" cellpadding="0" style="color:#333333;width:100%;border-collapse:collapse;">
        <tbody>
          <tr>
            <td class="MenuBarItem" align="center" valign="middle" style="background-color:#EFF3FB;width:25%;white-space:nowrap;">
              <a id="ctl00_topmenubar_DataList1_ctl00_HyperLink1" href="../default.aspx">Home</a>
            </td>
            <td class="MenuBarItem" align="center" valign="middle" style="background-color:White;width:25%;white-space:nowrap;">
              <a id="ctl00_topmenubar_DataList1_ctl01_HyperLink1" href="../about.aspx">About</a>
            </td>
            <td class="MenuBarItem" align="center" valign="middle" style="background-color:#EFF3FB;width:25%;white-space:nowrap;">
              <a id="ctl00_topmenubar_DataList1_ctl02_HyperLink1" href="http://www.binaryintellect.com">ASP.NET Online Course</a>
            </td>
            <td class="MenuBarItem" align="center" valign="middle" style="background-color:White;width:25%;white-space:nowrap;">
              <a id="ctl00_topmenubar_DataList1_ctl03_HyperLink1" href="http://www.bipinjoshi.org">Shambhavi Mudra</a>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
    <div id="main">
      <div id="leftcolumn">
        <img id="ctl00_imgSpacer" src="../images/misc/leftcolumnspacer.png">
        <br>
        <table id="ctl00_coursesMenu_DataList1" class="MenuPad" cellspacing="0" style="border-collapse:collapse;">
          <tbody>
            <tr>
              <td class="MenuHeading" align="center" style="white-space:nowrap;">
                <span id="ctl00_coursesMenu_DataList1_ctl00_Label1" style="font-weight:bold;">Online Courses</span>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_coursesMenu_DataList1_ctl01_HyperLink1" href="http://www.binaryintellect.com/courses/fa959470-2e71-4eb5-9fdc-fceb7971c71b">ASP.NET Core</a>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_coursesMenu_DataList1_ctl02_HyperLink1" href="http://www.binaryintellect.com/courses/63e78acd-8c7a-4da6-9015-dddd184f3068">Design Patterns</a>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_coursesMenu_DataList1_ctl03_HyperLink1" href="http://www.bipinjoshi.org">Shambhavi Mudra</a>
              </td>
            </tr>
          </tbody>
        </table>
        <br>
        <div class="AdContainer">
          <center>
            <a href="http://www.discountasp.net" target="_blank">
<img src="/images/discountasp.gif" border="0">
</a>
          </center>
        </div>
        <br>
        <table id="ctl00_categoriesMenu_DataList1" class="MenuPad" cellspacing="0" style="border-collapse:collapse;">
          <tbody>
            <tr>
              <td class="MenuHeading" align="center" style="white-space:nowrap;">
                <span id="ctl00_categoriesMenu_DataList1_ctl00_Label1" style="font-weight:bold;">Categories</span>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_categoriesMenu_DataList1_ctl01_HyperLink1" href="../categories/be3270c7-740a-4ce4-aded-95d6d601d651.aspx">ASP.NET Core</a>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_categoriesMenu_DataList1_ctl02_HyperLink1" href="../categories/dac01a23-ffc5-4584-aedf-617d92339767.aspx">Blazor</a>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_categoriesMenu_DataList1_ctl03_HyperLink1" href="../categories/5970c420-64b5-4d71-a4db-36a7f7d8b810.aspx">Web API</a>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_categoriesMenu_DataList1_ctl04_HyperLink1" href="../categories/023b938c-1583-4a06-8d86-31e4a55d7500.aspx">ASP.NET MVC</a>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_categoriesMenu_DataList1_ctl05_HyperLink1" href="../categories/22d7f3e3-a683-4510-8930-d37e38c671f1.aspx">ASP.NET</a>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_categoriesMenu_DataList1_ctl06_HyperLink1" href="../categories/751a6da8-ef7b-4b69-9bf6-a1ad03755b6b.aspx">Data Access</a>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_categoriesMenu_DataList1_ctl07_HyperLink1" href="../categories/5a11fcea-7177-4bde-9b0f-8a7884cb7880.aspx">.NET / Visual Studio</a>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_categoriesMenu_DataList1_ctl08_HyperLink1" href="../categories/25543196-65d4-46fc-93e2-c7144805882a.aspx">JavaScript / jQuery</a>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_categoriesMenu_DataList1_ctl09_HyperLink1" href="../categories/fc193202-2f03-4aee-8106-ec182acd3e97.aspx">HTML5</a>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_categoriesMenu_DataList1_ctl10_HyperLink1" href="../categories/ca35eae7-3ef7-4ffa-af08-cc06d0943fb3.aspx">Web Services</a>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_categoriesMenu_DataList1_ctl11_HyperLink1" href="../categories/503191ae-787e-4109-a3c4-75ebcd078541.aspx">Windows Forms</a>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_categoriesMenu_DataList1_ctl12_HyperLink1" href="../categories/332d650f-5313-4a91-9ee7-4d6815f861fc.aspx">Projects</a>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_categoriesMenu_DataList1_ctl13_HyperLink1" href="../categories/646e6280-f859-40f4-bc1c-27db77030f2b.aspx">Book Reviews</a>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_categoriesMenu_DataList1_ctl14_HyperLink1" href="../categories/5f4986ff-9b56-4529-bbcd-c4753aa0951b.aspx">Videos</a>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_categoriesMenu_DataList1_ctl15_HyperLink1" href="searcharticles.aspx">Search Articles</a>
              </td>
            </tr>
          </tbody>
        </table>
        <br>
        <table id="ctl00_followMenu_DataList1" class="MenuPad" cellspacing="0" style="border-collapse:collapse;">
          <tbody>
            <tr>
              <td class="MenuHeading" align="center" style="white-space:nowrap;">
                <span id="ctl00_followMenu_DataList1_ctl00_Label1" style="font-weight:bold;">Article Updates</span>
              </td>
            </tr>
            <tr>
              <td class="MenuItem" align="center" style="white-space:nowrap;">
                <a id="ctl00_followMenu_DataList1_ctl01_HyperLink1" href="rssfeed.aspx">RSS Feed</a>
              </td>
            </tr>
          </tbody>
        </table>
        <br>
        <span>
          <center>
            <!-- <a href="/about.aspx" target="_blank">
<img src="/images/books/html5.png" border="0"/>
</a> -->
            <a href="http://www.apress.com/9781484218471"><img src="/images/books/XmlCsSmall.jpg" border="0"></a>
          </center>
          <center>
            <a href="/about.aspx" target="_blank">
<img src="/images/books/jquery.png" border="0">
</a>
          </center>
          <center>
            <a href="/about.aspx" target="_blank">
<img src="/images/books/dpsmall.jpg" border="0">
</a>
          </center>
          <center>
            <a href="http://www.bipinjoshi.org" target="_blank">
<img src="/images/books/nsdsmall.jpg" border="0">
</a>
            <br>
            <a href="http://www.bipinjoshi.org" target="_blank">
<img src="/images/books/ddh.png" border="0">
</a>
          </center>
        </span><span>
          <div data-type="ad" data-publisher="lqm.bipinjoshinet.site" data-format="160x600" data-zone="ros2"></div>
          <br>
        </span><span>
          <div data-type="ad" data-publisher="lqm.bipinjoshinet.site" data-zone="ron" data-format="160x600"></div>
        </span>
      </div>
      <div id="middlecolumn">
        <span><!-- <div class="Note" style="font-weight:600;text-align:center">
ASP.NET Core 5.0 : MVC, Razor Pages, Web API, EF Core, Blazor, Design Patterns, and more. Private online coaching for software developers. Click <a href="http://www.binaryintellect.com">here</a> for more details.
</div> -->
          <!--
<div data-type="ad" data-publisher="lqm.bipinjoshinet.site" data-format="728x90" data-zone="ros11"></div>
-->
          <center>
            <div class="Note">
              <strong>
                <a href="http://www.bipinjoshi.org">अजपा जप आणि शांभवी मुद्रा ऑनलाईन कोर्स</a> : श्वास, मंत्र, मुद्रा आणि ध्यान यांच्या सहाय्याने मनःशांती, एकाग्रता, चक्र संतुलन आणि कुंडलिनी जागृती. अधिक माहिती आणि आगामी तारखांसाठी
                <a href="http://www.bipinjoshi.org">येथे जा</a>. </strong>
            </div>
          </center>
          <br>
          <br>
        </span>
        <div>
          <h1>Use SqlDataReader to Read Data in ASP.NET Core</h1>
          <p align="center"><img src="content/Images/T_AdoNetAspNetCore_01.jpg" style="object-fit: cover;width:100%;height:100%"></p>
          <p>In the <a href="0c8f13fd-ef6d-4346-a9d3-0f6f810924a2.aspx">previous article</a> we learned the basics of the ADO.NET data provider for SQL Server. We also took a glance at the SQL Server data provider's object model. Now it's time to put
            those objects to use in a simple CRUD web application. To that end this article kicks off the development by creating a simple repository for performing the CRUD operations.</p>
          <p>In this article we create a simple repository with five methods namely SelectAll(), SelectByID(), Insert(), Update(), and Delete(). These methods will be asynchronous and will do the respective task. </p>
          <p>To get started, create a new ASP.NET Core web application using the empty project template. If you created a project as a pert of the <a href="0c8f13fd-ef6d-4346-a9d3-0f6f810924a2.aspx">previous article,</a> you can open the same project
            to develop this example.</p>
          <p>Then open NuGet package manager dialog and install the Microsoft.Data.SqlClient package as shown below:</p>
          <p><img src="content/Images/T_AdoNetAspNetCore_02_01.png"></p>
          <p>And</p>
          <p><img src="content/Images/T_AdoNetAspNetCore_02_02.png"></p>
          <p>Then add a new C# class file named GlobalUsings.cs in the project root and place the following code in it.</p>
          <pre><strong>global using System.Data;
global using Microsoft.Data.SqlClient;
</strong>global using System.ComponentModel.DataAnnotations;
global using AdoNetIDemo.DataAccess;</pre>
          <p>We imported a few namespaces globally. Especially System.Data and Microsoft.Data.SqlClient are important because they provide the main data access classes.</p>
          <p>Next, open appsettings.json file and place the following database connection string.</p>
          <pre>"ConnectionStrings": {
  "AppDb": <strong>"data source=.;initial catalog=Northwind;
integrated security=true"</strong>
}</pre>
          <p>Here, I am going to use the Northwind database and Customers table for this example. Make sure to change the database connection string as per your setup.</p>
          <p>Next, add a folder named DataAccess in the project root and then add a new C# class file called Customer.cs in it.</p>
          <p>Once we fetch data from the Customers table we need to send it to the UI. We will create a <a href="https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/records?WT.mc_id=DT-MVP-7776" target="_blank">
record type</a> called Customer for this purpose. You could have also used traditional C# class instead of a record.</p>
          <p>Open the Customer.cs file and add the following code to it:</p>
          <pre>namespace AdoNetIDemo.DataAccess;

public record Customer(
    [Required] string CustomerID, 
    [Required] string CompanyName, 
    [Required] string ContactName, 
    [Required] string Country
);</pre>
          <p>As you can see, we declared a record called Customer that has four properties namely CustomerID, CompanyName, ContactName, and Country. All the properties are decorated with [Required] attribute for the sake of data validation.</p>
          <p>I have used a shortcut way of declaring a record (positional record). If you want you can also use a more elaborate class-like syntax involving init only properties :</p>
          <pre>public record Customer
{
    [Required]
    public string CustomerID { get; <strong>init;</strong> }  

    [Required]
    public string CompanyName { get; <strong>init;</strong> }

    [Required]
    public string ContactName { get; <strong>init;</strong> }

    [Required]
    public string Country { get; <strong>init;</strong> }
}</pre>
          <p>You can read more about record type in the official documentation <a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record?WT.mc_id=DT-MVP-7776" target="_blank">
here</a> and <a href="https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/types/records?WT.mc_id=DT-MVP-7776" target="_blank">
here</a>.</p>
          <p>Add the AdoNetIDemo.DataAccess namespace to GlobalUsings.cs file before moving ahead.</p>
          <p>Now add a new interface named ICustomerRepository to the DataAccess folder and write the following code in it.</p>
          <pre>namespace AdoNetIDemo.DataAccess;

public interface <strong>ICustomerRepository</strong>
{
    Task&lt;List&lt;Customer&gt;&gt; <strong>SelectAll</strong><strong>()</strong>;
    Task&lt;Customer&gt; <strong>SelectByID</strong><strong>(string id)</strong>;   
    Task&lt;int&gt; <strong>Insert(Customer customer)</strong>;
    Task&lt;int&gt; <strong>Update(Customer customer)</strong>;
    Task&lt;int&gt; <strong>Delete(int id)</strong>;
}</pre>
          <p>The ICustomerRepository interface contains the skeleton of our repository class and has five methods - SelectAll(), SelectByID(), Insert(), Update(), Delete().</p>
          <p>Since we want our repository to be async, we return Task from the interface methods.</p>
          <p>Now add CustomerRepository class into the DataAccess folder and implement ICustomerRepository interface in it.</p>
          <pre>namespace AdoNetIDemo.DataAccess;


public class <strong>CustomerRepository : ICustomerRepository</strong>
{
  // your code here
}</pre>
          <p>The CustomerRepository class will need the database connection string stored in the appsettings.json file. So, we inject IConfiguration object into the constructor and read the connection string as shown below:</p>
          <pre>private readonly string connectionString;

public CustomerRepository(IConfiguration config)
{
    connectionString = config.GetConnectionString("AppDb");
}</pre>
          <p>The GetConnectionString() method of IConfiguration accepts the connection string name from the ConnectionStrings section and returns that connecting string value.</p>
          <p>We will now implement the SelectAll() method of&nbsp; the repository that reads the Customers table. Take a look :</p>
          <pre>public async Task&lt;List&lt;Customer&gt;&gt; SelectAll()
{
    <strong>using var connection = new SqlConnection(connectionString);</strong>

    var query = "Select CustomerID, CompanyName, ContactName, 
Country From Customers Order By CustomerID";

    <strong>using var command = new SqlCommand(query, connection);</strong>

    try
    {
        await <strong>connection.OpenAsync()</strong>;
        using var reader = await <strong>command.ExecuteReaderAsync()</strong>;
        List&lt;Customer&gt; items = null;
        if (<strong>reader.HasRows</strong>)
        {
            items = new List&lt;Customer&gt;();
            while (await <strong>reader.ReadAsync()</strong>)
            {
                var item = new Customer(
                    CustomerID: reader.GetString(0),
                    CompanyName: reader.GetString(1),
                    ContactName: reader.GetString(2),
                    Country: reader.GetString(3));
                items.Add(item);
            }
        }
        await <strong>reader.CloseAsync()</strong>;
        await <strong>connection.CloseAsync()</strong>;
        return items;
    }
    catch
    {
        if (<strong>connection.State</strong> != ConnectionState.Closed)
        {
            await <strong>connection.CloseAsync()</strong>;
        }
        return null;
    }
}</pre>
          <p>This code begins by creating a new SqlConnection object. Notice the use of <a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement?WT.mc_id=DT-MVP-7776" target="_blank">
using declaration</a> while creating the SqlConnection. That will ensure that the resources consumed by the connection are reclaimed properly when the connection is closed. </p>
          <p>We are interested to retrieve all the Customers from the database (We need CustomerID, CompanyName, ContactName, and Country columns). So, we store a SELECT query for doing that in a string variable. </p>
          <p>Then we create a SqlCommand object by specifying this query and the SqlConnection. A SqlCommand object represents a select or action query (or stored procedure) that you intend to execute on the database. A SqlCommand requires an open
            database connection to execute any queries. So, we open the database connection by calling OpenAsync() method of SqlConnection.</p>
          <p>To execute this SELECT query against the database we use ExecuteReaderAsync() method of SqlCommand. The ExecuteReaderAsync() method executes the query and returns a SqlDataReader. A SqlDataReader is read-only, forward-only cursor that
            allows you to iterate through the result set and read one record at a time.</p>
          <p>To read and store the customer data we create a List of Customer records (C# record). It makes sense to iterate through the result set only if there are any rows in it. So, we check the HasRows property of SqlDataReader that tells us
            just that. If HasRows returns true we go ahead and run a while loop. Initially, SqlDataReader's current row pointer is placed before the first row. Calling ReadAsync() method does two things - it advances the row pointer to the next row
            and reads data for that row.</p>
          <p>Inside the while loop we create a Customer item by specifying its positional properties - CustomerID, CompanyName, ContactName, and Country. To set values to these positional properties we use GetString() method of SqlDataReader. The
            GetString() method accepts a column index (index starts from 0 and sequence is same as they appear in the query) and returns the value from that column. Just like GetString() there are different methods for different data types such as
            GetInt32(), GetBoolean(), and GetDateTime().</p>
          <p>Once a new Customer item is created we add it to the List&lt;Customer&gt;. The ReadAsync() method returns false when it reaches past the end of the result set. We then close the SqlDataReader and SqlConnection by calling their
            CloseAsync() methods respectively. Strictly speaking closing a connection also closes the data reader. Here, I am explicitly closing both of them just to highlight that SqlDataReader has CloseAsync() method (you will learn more about it
            in a later part of this article series).</p>
          <p>Finally, List&lt;Customer&gt; is returned to the caller. </p>
          <p>The whole while loop and data reading logic is placed inside a try-catch block to trap any unexpected errors. In case of any error, we close the SqlConnection if it's open and return null to the caller. The State property is an
            enumeration of type ConnectionState and contains various possible values such as Closed, Open, and Broken.</p>
          <p>This completes the SelectAll() method.</p>
          <p>Now let's add the SelectByID() method. &nbsp;</p>
          <pre>public async Task&lt;Customer&gt; SelectByID(string id)
{
    using var connection = new SqlConnection(connectionString);

    var query = "Select CustomerID, CompanyName, ContactName, 
Country From Customers <strong>Where CustomerID = @CustomerID</strong>";

    using var command = new SqlCommand(query, connection);

    <strong>command.Parameters.AddWithValue("CustomerID", id);</strong>

    try
    {
        await connection.OpenAsync();
        using var reader = await command.ExecuteReaderAsync();
        Customer item = null;
        if (reader.HasRows)
        {
            while (await reader.ReadAsync())
            {
                item = new Customer(
                    CustomerID: reader.GetString
(<strong>reader.GetOrdinal("CustomerID")</strong>),
                    CompanyName: reader.GetString
(<strong>reader.GetOrdinal("CompanyName")</strong>),
                    ContactName: reader.GetString
(<strong>reader.GetOrdinal("ContactName")</strong>),
                    Country: reader.GetString
(<strong>reader.GetOrdinal("Country")</strong>));
            }
        }
        await reader.CloseAsync();
        await connection.CloseAsync();
        return item;
    }
    catch
    {
        if (connection.State != ConnectionState.Closed)
        {
            await connection.CloseAsync();
        }
        return null;
    }
}</pre>
          <p>The SelectByID() method accepts a CustomerID and returns the matching Customer to the caller. The overall working of this method is similar to SelectAll() because here also we need to read Customer data from the database. However, this
            time we fetch only a single Customer row. Notice the code marked in bold letters. </p>
          <p>The SELECT query now has WHERE with a @CustomerID parameter. To specify this query parameter's value we use AddWithValue() method of the SqlCommand's Parameter collection. The AddWithValue() method takes the parameter name and its value.
            Internally, it adds a SqlParameter object to the Parameters collection.</p>
          <p>This time instead of creating a List&lt;Customer&gt; we create just a single Customer record. The item gets filled inside the while loop and is then returned to the caller.</p>
          <p>Previously we used GetString() calls and specified the column index. Many a times knowing and hard-coding a column index can be problematic. So, this time we use GetOrdinal() method of SqlDataReader. The GetOrdinal() method accepts a
            column name and returns its index.</p>
          <p>This completes the SelectByID() method.</p>
          <p>In the next part of this article series we will add Insert(), Update(), and Delete() methods to the CustomerRepository.&nbsp;</p>
          <p>That's it for now! Keep coding!!</p>
          <center>
          </center>
        </div>
        <br>
        <div>
          <div class="AuthorProfile" style="font-weight:500">
            <b>Bipin Joshi</b> is an independent software consultant and trainer by profession specializing in Microsoft web development technologies. Having embraced the Yoga way of life he is also a meditation teacher and spiritual guide to his
            students. He is a prolific author and writes regularly about software development and yoga on his websites. He is programming, meditating, writing, and teaching for over 27 years. To know more about his ASP.NET online courses go
            <a href="http://www.binaryintellect.com">here</a>. More details about his Kriya and Meditation online course are available <a href="http://www.bipinjoshi.org">here</a>.
          </div>
        </div>
        <br>
        <center>
          <span id="ctl00_ContentPlaceHolder1_lblPostDate" style="font-weight:bold;">Posted On : 08 August 2022</span>
        </center>
        <br>
        <center>
          <script type="text/javascript" src="https://platform-api.sharethis.com/js/sharethis.js#property=6451d137f204d5001a5bdaca&amp;product=inline-share-buttons&amp;source=platform" async="async"></script>
          <div class="sharethis-inline-share-buttons st-center st-has-labels  st-inline-share-buttons st-animated" id="st-1">
            <div class="st-btn st-first" data-network="facebook" style="display: inline-block;">
              <img alt="facebook sharing button" src="https://platform-cdn.sharethis.com/img/facebook.svg">
              <span class="st-label">Share</span>
            </div>
            <div class="st-btn" data-network="twitter" style="display: inline-block;">
              <img alt="twitter sharing button" src="https://platform-cdn.sharethis.com/img/twitter.svg">
              <span class="st-label">Tweet</span>
            </div>
            <div class="st-btn" data-network="whatsapp" style="display: inline-block;">
              <img alt="whatsapp sharing button" src="https://platform-cdn.sharethis.com/img/whatsapp.svg">
              <span class="st-label">Share</span>
            </div>
            <div class="st-btn" data-network="linkedin" style="display: inline-block;">
              <img alt="linkedin sharing button" src="https://platform-cdn.sharethis.com/img/linkedin.svg">
              <span class="st-label">Share</span>
            </div>
            <div class="st-btn st-last" data-network="sharethis" style="display: inline-block;">
              <img alt="sharethis sharing button" src="https://platform-cdn.sharethis.com/img/sharethis.svg">
              <span class="st-label">Share</span>
            </div>
          </div>
        </center>
        <br>
        <div>
        </div>
        <br><br><br>
        <div id="ctl00_ContentPlaceHolder1_gridPopularFromCategory_pnlShort">
          <div>
            <table cellspacing="0" cellpadding="6" id="ctl00_ContentPlaceHolder1_gridPopularFromCategory_GridView2" style="color:#333333;border-color:#5D7B9D;border-width:1px;border-style:Solid;width:100%;border-collapse:collapse;">
              <tbody>
                <tr align="center" style="color:White;background-color:#5D7B9D;font-weight:bold;">
                  <th scope="col">Popular from this category</th>
                </tr>
                <tr style="color:#333333;background-color:#F7F6F3;">
                  <td><a href="fbc96859-8a31-4735-baeb-7adcbc521b30.aspx">Executing Raw SQL Queries using Entity Framework</a></td>
                </tr>
                <tr style="color:#284775;background-color:White;">
                  <td><a href="30738a7c-5176-4333-aa83-98eab8548da5.aspx">Working with Stored Procedures in Entity Framework - Part 2</a></td>
                </tr>
                <tr style="color:#333333;background-color:#F7F6F3;">
                  <td><a href="c1bff938-1789-4501-8161-3f38bc465a8b.aspx">What to do when SaveChanges() fails?</a></td>
                </tr>
                <tr style="color:#284775;background-color:White;">
                  <td><a href="3babaf92-64ee-491e-8401-b7f52befada3.aspx">Uploading and Retrieving Images From SQL Server</a></td>
                </tr>
                <tr style="color:#333333;background-color:#F7F6F3;">
                  <td><a href="98ab41a4-3a69-42c6-96d9-b639ce68a0f4.aspx">Working with Stored Procedures in Entity Framework - Part 1</a></td>
                </tr>
                <tr style="color:#284775;background-color:White;">
                  <td><a href="fbea3517-b0c8-4e79-bc52-cc75e0b1b86f.aspx">Developing generic data access layer using ADO.NET 2.0</a></td>
                </tr>
                <tr style="color:#333333;background-color:#F7F6F3;">
                  <td><a href="c7f854b4-b213-4216-ba30-67c6584dc376.aspx">Working with Binary Large Objects (BLOBs) Using SQL Server and ADO.NET</a></td>
                </tr>
                <tr style="color:#284775;background-color:White;">
                  <td><a href="165bb877-27ee-4efa-9fa3-40cd0cf69e49.aspx">Wrapping multiple calls to SaveChanges() in a single transaction</a></td>
                </tr>
                <tr style="color:#333333;background-color:#F7F6F3;">
                  <td><a href="432e4904-754c-4425-ae93-c6142c2b943f.aspx">Use DataReader Cleverly</a></td>
                </tr>
                <tr style="color:#284775;background-color:White;">
                  <td><a href="d07c7f36-5d4c-4195-817a-bdddbbc11041.aspx">Generic Data Access Application Block for .NET</a></td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
        <br>
        <center>
          <span>
            <div data-type="ad" data-publisher="lqm.bipinjoshinet.site" data-zone="ron" data-format="300x250"></div>
          </span>
        </center>
      </div>
      <div id="rightcolumn"></div>
    </div>
    <div id="footer">
      <div style="padding-top:11px"> Copyright © binaryintellect.net. All rights reserved. </div>
      <div>
        <a href="/legal.aspx">Read Copyright and Legal Terms of Use</a>
      </div>
      <div>
        <a href="http://www.copyscape.com/" target="_blank">
							<img src="http://banners.copyscape.com/img/copyscape-banner-blue-200x25.png" width="200" height="25" border="0" alt="Protected by Copyscape" title="Protected by Copyscape Plagiarism Checker - Do not copy content from this page.">
						</a>
      </div>
      <div>
        <a href="http://www.discountasp.net">Hosted by DiscountASP.net</a>
      </div>
      <div class="CenteredNormalText" style="padding:3px">
        <a href="https://www.facebook.com/joshibipin">
        <img src="/images/social/facebook.jpg">
    </a>
        <a href="https://twitter.com/joshibipin">
        <img src="/images/social/twitter.png">
	</a>
        <a href="https://www.linkedin.com/in/joshibipin">
        <img src="/images/social/linkedin.png">
	</a>
        <a href="/contact.aspx">
        <img src="/images/social/email.jpg">
    </a>
        <a href="/articles/rssfeed.aspx">
        <img src="/images/social/rss.png">
	</a>
      </div>
    </div>
  </div>
  <span>
    <script type="text/javascript">
      function _dmBootstrap(file) {
        var _dma = document.createElement('script');
        _dma.type = 'text/javascript';
        _dma.async = true;
        _dma.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + file;
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(_dma);
      }

      function _dmFollowup(file) {
        if (typeof DMAds === 'undefined') _dmBootstrap('cdn2.DeveloperMedia.com/a.min.js');
      }
      (function() {
        _dmBootstrap('cdn1.DeveloperMedia.com/a.min.js');
        setTimeout(_dmFollowup, 2000);
      })();
    </script>
  </span>
</form>

Text Content

Home About ASP.NET Online Course Shambhavi Mudra




Online Courses ASP.NET Core Design Patterns Shambhavi Mudra





Categories ASP.NET Core Blazor Web API ASP.NET MVC ASP.NET Data Access .NET /
Visual Studio JavaScript / jQuery HTML5 Web Services Windows Forms Projects Book
Reviews Videos Search Articles


Article Updates RSS Feed






अजपा जप आणि शांभवी मुद्रा ऑनलाईन कोर्स : श्वास, मंत्र, मुद्रा आणि ध्यान यांच्या
सहाय्याने मनःशांती, एकाग्रता, चक्र संतुलन आणि कुंडलिनी जागृती. अधिक माहिती आणि
आगामी तारखांसाठी येथे जा.




USE SQLDATAREADER TO READ DATA IN ASP.NET CORE



In the previous article we learned the basics of the ADO.NET data provider for
SQL Server. We also took a glance at the SQL Server data provider's object
model. Now it's time to put those objects to use in a simple CRUD web
application. To that end this article kicks off the development by creating a
simple repository for performing the CRUD operations.

In this article we create a simple repository with five methods namely
SelectAll(), SelectByID(), Insert(), Update(), and Delete(). These methods will
be asynchronous and will do the respective task.

To get started, create a new ASP.NET Core web application using the empty
project template. If you created a project as a pert of the previous article,
you can open the same project to develop this example.

Then open NuGet package manager dialog and install the Microsoft.Data.SqlClient
package as shown below:



And



Then add a new C# class file named GlobalUsings.cs in the project root and place
the following code in it.

global using System.Data;
global using Microsoft.Data.SqlClient;
global using System.ComponentModel.DataAnnotations;
global using AdoNetIDemo.DataAccess;

We imported a few namespaces globally. Especially System.Data and
Microsoft.Data.SqlClient are important because they provide the main data access
classes.

Next, open appsettings.json file and place the following database connection
string.

"ConnectionStrings": {
  "AppDb": "data source=.;initial catalog=Northwind;
integrated security=true"
}

Here, I am going to use the Northwind database and Customers table for this
example. Make sure to change the database connection string as per your setup.

Next, add a folder named DataAccess in the project root and then add a new C#
class file called Customer.cs in it.

Once we fetch data from the Customers table we need to send it to the UI. We
will create a record type called Customer for this purpose. You could have also
used traditional C# class instead of a record.

Open the Customer.cs file and add the following code to it:

namespace AdoNetIDemo.DataAccess;

public record Customer(
    [Required] string CustomerID, 
    [Required] string CompanyName, 
    [Required] string ContactName, 
    [Required] string Country
);

As you can see, we declared a record called Customer that has four properties
namely CustomerID, CompanyName, ContactName, and Country. All the properties are
decorated with [Required] attribute for the sake of data validation.

I have used a shortcut way of declaring a record (positional record). If you
want you can also use a more elaborate class-like syntax involving init only
properties :

public record Customer
{
    [Required]
    public string CustomerID { get; init; }  

    [Required]
    public string CompanyName { get; init; }

    [Required]
    public string ContactName { get; init; }

    [Required]
    public string Country { get; init; }
}

You can read more about record type in the official documentation here and here.

Add the AdoNetIDemo.DataAccess namespace to GlobalUsings.cs file before moving
ahead.

Now add a new interface named ICustomerRepository to the DataAccess folder and
write the following code in it.

namespace AdoNetIDemo.DataAccess;

public interface ICustomerRepository
{
    Task<List<Customer>> SelectAll();
    Task<Customer> SelectByID(string id);   
    Task<int> Insert(Customer customer);
    Task<int> Update(Customer customer);
    Task<int> Delete(int id);
}

The ICustomerRepository interface contains the skeleton of our repository class
and has five methods - SelectAll(), SelectByID(), Insert(), Update(), Delete().

Since we want our repository to be async, we return Task from the interface
methods.

Now add CustomerRepository class into the DataAccess folder and implement
ICustomerRepository interface in it.

namespace AdoNetIDemo.DataAccess;


public class CustomerRepository : ICustomerRepository
{
  // your code here
}

The CustomerRepository class will need the database connection string stored in
the appsettings.json file. So, we inject IConfiguration object into the
constructor and read the connection string as shown below:

private readonly string connectionString;

public CustomerRepository(IConfiguration config)
{
    connectionString = config.GetConnectionString("AppDb");
}

The GetConnectionString() method of IConfiguration accepts the connection string
name from the ConnectionStrings section and returns that connecting string
value.

We will now implement the SelectAll() method of  the repository that reads the
Customers table. Take a look :

public async Task<List<Customer>> SelectAll()
{
    using var connection = new SqlConnection(connectionString);

    var query = "Select CustomerID, CompanyName, ContactName, 
Country From Customers Order By CustomerID";

    using var command = new SqlCommand(query, connection);

    try
    {
        await connection.OpenAsync();
        using var reader = await command.ExecuteReaderAsync();
        List<Customer> items = null;
        if (reader.HasRows)
        {
            items = new List<Customer>();
            while (await reader.ReadAsync())
            {
                var item = new Customer(
                    CustomerID: reader.GetString(0),
                    CompanyName: reader.GetString(1),
                    ContactName: reader.GetString(2),
                    Country: reader.GetString(3));
                items.Add(item);
            }
        }
        await reader.CloseAsync();
        await connection.CloseAsync();
        return items;
    }
    catch
    {
        if (connection.State != ConnectionState.Closed)
        {
            await connection.CloseAsync();
        }
        return null;
    }
}

This code begins by creating a new SqlConnection object. Notice the use of using
declaration while creating the SqlConnection. That will ensure that the
resources consumed by the connection are reclaimed properly when the connection
is closed.

We are interested to retrieve all the Customers from the database (We need
CustomerID, CompanyName, ContactName, and Country columns). So, we store a
SELECT query for doing that in a string variable.

Then we create a SqlCommand object by specifying this query and the
SqlConnection. A SqlCommand object represents a select or action query (or
stored procedure) that you intend to execute on the database. A SqlCommand
requires an open database connection to execute any queries. So, we open the
database connection by calling OpenAsync() method of SqlConnection.

To execute this SELECT query against the database we use ExecuteReaderAsync()
method of SqlCommand. The ExecuteReaderAsync() method executes the query and
returns a SqlDataReader. A SqlDataReader is read-only, forward-only cursor that
allows you to iterate through the result set and read one record at a time.

To read and store the customer data we create a List of Customer records (C#
record). It makes sense to iterate through the result set only if there are any
rows in it. So, we check the HasRows property of SqlDataReader that tells us
just that. If HasRows returns true we go ahead and run a while loop. Initially,
SqlDataReader's current row pointer is placed before the first row. Calling
ReadAsync() method does two things - it advances the row pointer to the next row
and reads data for that row.

Inside the while loop we create a Customer item by specifying its positional
properties - CustomerID, CompanyName, ContactName, and Country. To set values to
these positional properties we use GetString() method of SqlDataReader. The
GetString() method accepts a column index (index starts from 0 and sequence is
same as they appear in the query) and returns the value from that column. Just
like GetString() there are different methods for different data types such as
GetInt32(), GetBoolean(), and GetDateTime().

Once a new Customer item is created we add it to the List<Customer>. The
ReadAsync() method returns false when it reaches past the end of the result set.
We then close the SqlDataReader and SqlConnection by calling their CloseAsync()
methods respectively. Strictly speaking closing a connection also closes the
data reader. Here, I am explicitly closing both of them just to highlight that
SqlDataReader has CloseAsync() method (you will learn more about it in a later
part of this article series).

Finally, List<Customer> is returned to the caller.

The whole while loop and data reading logic is placed inside a try-catch block
to trap any unexpected errors. In case of any error, we close the SqlConnection
if it's open and return null to the caller. The State property is an enumeration
of type ConnectionState and contains various possible values such as Closed,
Open, and Broken.

This completes the SelectAll() method.

Now let's add the SelectByID() method.  

public async Task<Customer> SelectByID(string id)
{
    using var connection = new SqlConnection(connectionString);

    var query = "Select CustomerID, CompanyName, ContactName, 
Country From Customers Where CustomerID = @CustomerID";

    using var command = new SqlCommand(query, connection);

    command.Parameters.AddWithValue("CustomerID", id);

    try
    {
        await connection.OpenAsync();
        using var reader = await command.ExecuteReaderAsync();
        Customer item = null;
        if (reader.HasRows)
        {
            while (await reader.ReadAsync())
            {
                item = new Customer(
                    CustomerID: reader.GetString
(reader.GetOrdinal("CustomerID")),
                    CompanyName: reader.GetString
(reader.GetOrdinal("CompanyName")),
                    ContactName: reader.GetString
(reader.GetOrdinal("ContactName")),
                    Country: reader.GetString
(reader.GetOrdinal("Country")));
            }
        }
        await reader.CloseAsync();
        await connection.CloseAsync();
        return item;
    }
    catch
    {
        if (connection.State != ConnectionState.Closed)
        {
            await connection.CloseAsync();
        }
        return null;
    }
}

The SelectByID() method accepts a CustomerID and returns the matching Customer
to the caller. The overall working of this method is similar to SelectAll()
because here also we need to read Customer data from the database. However, this
time we fetch only a single Customer row. Notice the code marked in bold
letters.

The SELECT query now has WHERE with a @CustomerID parameter. To specify this
query parameter's value we use AddWithValue() method of the SqlCommand's
Parameter collection. The AddWithValue() method takes the parameter name and its
value. Internally, it adds a SqlParameter object to the Parameters collection.

This time instead of creating a List<Customer> we create just a single Customer
record. The item gets filled inside the while loop and is then returned to the
caller.

Previously we used GetString() calls and specified the column index. Many a
times knowing and hard-coding a column index can be problematic. So, this time
we use GetOrdinal() method of SqlDataReader. The GetOrdinal() method accepts a
column name and returns its index.

This completes the SelectByID() method.

In the next part of this article series we will add Insert(), Update(), and
Delete() methods to the CustomerRepository. 

That's it for now! Keep coding!!


Bipin Joshi is an independent software consultant and trainer by profession
specializing in Microsoft web development technologies. Having embraced the Yoga
way of life he is also a meditation teacher and spiritual guide to his students.
He is a prolific author and writes regularly about software development and yoga
on his websites. He is programming, meditating, writing, and teaching for over
27 years. To know more about his ASP.NET online courses go here. More details
about his Kriya and Meditation online course are available here.

Posted On : 08 August 2022

Share
Tweet
Share
Share
Share






Popular from this category Executing Raw SQL Queries using Entity Framework
Working with Stored Procedures in Entity Framework - Part 2 What to do when
SaveChanges() fails? Uploading and Retrieving Images From SQL Server Working
with Stored Procedures in Entity Framework - Part 1 Developing generic data
access layer using ADO.NET 2.0 Working with Binary Large Objects (BLOBs) Using
SQL Server and ADO.NET Wrapping multiple calls to SaveChanges() in a single
transaction Use DataReader Cleverly Generic Data Access Application Block for
.NET




Copyright © binaryintellect.net. All rights reserved.
Read Copyright and Legal Terms of Use

Hosted by DiscountASP.net