June 2008 - Posts

I had to find some work-a-round for a scrollable repeater. The way I want it to be is to have fix headers with able to vertically scrollable. I found lots of example dealing for this solution with CSS and JavaScript. Luckily, I found one which works in both IE and FF. I managed to make one example here:

Here is the Complete ASPX Code along with JavaScript which is suppose to be called on "onload" event. The Example is simply listing one DataTable with Name,  MobileNo and Address columns.

The Idea is, Place the Repeater inside a DIV layer which is having OverFlow style set to Scroll.
Next, design a repeater with a table mark-up inside which is splitted over HeaderTemplate, ItemTemplate and FooterTemplate; as you know Repeater Control is the only Web control that allows you to split markup tags across the templates.
Next, write a JavaScript which create one object of THEAD, one Clone of the Table Node; the table which we created inside the Repeater; and append the THEAD object inside the newly created Clone Node.
Finally, append this Clone Node inside another DIV which is created above the Repeater. That will serve as Fix Headers. Thats it!

<%--This DOCTYPE declaration is Required; unless would not work in FF--%>
<!DOCTYPE HTML ePUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>

    <script type="text/javascript" language="javascript">
    function fixHeader()
    {
        var t = document.getElementById("table");
        var thead = t.getElementsByTagName("thead")[0];
        var t1 = t.cloneNode(false);
        t1.appendChild(thead);
        tableHeader.appendChild(t1)
    }
    window.onload = fixHeader
</script>

</head>
<body>
    <form id="form1" runat="server">
        <div>
            <div id="tableHeader">
            </div>
            <div style="overflow: scroll; height: 100px; width: 500px">
                <asp:Repeater ID="Reapeter1" runat="server">
                    <HeaderTemplate>
                        <table id="table" width="500" style="table-layout: fixed; border:solid 1px black">
                            <thead>
                                <tr id="thead" style="width: 500px; background-color:#BEBEBE">
                                    <th>Name</th>
                                    <th>Mobile No</th>
                                    <th>Address</th>
                                </tr>
                            </thead>
                    </HeaderTemplate>
                    <ItemTemplate>
                        <tr>
                            <td>
                                <%#DataBinder.Eval(Container.DataItem, "Name")%>
                            </td>
                            <td>
                                <%#DataBinder.Eval(Container.DataItem,"MobileNo")%>
                            </td>
                            <td>
                                <%#DataBinder.Eval(Container.DataItem,"Address")%>
                            </td>
                        </tr>
                    </ItemTemplate>
                    <FooterTemplate>
                        </table>
                    </FooterTemplate>
                </asp:Repeater>
            </div>
        </div>
    </form>
</body>
</html>

On Code Behind side, I simply created one DataTable and assigned as DataSource to Repeater.

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("Name")); dt.Columns.Add(new DataColumn("MobileNo")); dt.Columns.Add(new DataColumn("Address"));
            DataRow dr = dt.NewRow();
            dr["Name"] = "Kaushal"; dr["MobileNo"] = "9876543210"; dr["Address"] = "Temp Address1"; dt.Rows.Add(dr);
            dr = dt.NewRow();
            dr["Name"] = "Naresh"; dr["MobileNo"] = "9786543210"; dr["Address"] = "Temp Address2"; dt.Rows.Add(dr);
            dr = dt.NewRow();
            dr["Name"] = "Pankaj"; dr["MobileNo"] = "9678541230"; dr["Address"] = "Temp Address3"; dt.Rows.Add(dr);
            dr = dt.NewRow();
            dr["Name"] = "Ravi"; dr["MobileNo"] = "9854712547"; dr["Address"] = "Temp Address4"; dt.Rows.Add(dr);
            dr = dt.NewRow();
            dr["Name"] = "Haresh"; dr["MobileNo"] = "9854712547"; dr["Address"] = "Temp Address5"; dt.Rows.Add(dr);
            dr = dt.NewRow();
            dr["Name"] = "Nirav"; dr["MobileNo"] = "9874124758"; dr["Address"] = "Temp Address6"; dt.Rows.Add(dr);
            Reapeter1.DataSource = dt;
            Reapeter1.DataBind();
        }
    }

 

Posted by kaushalparik | 7 comment(s)
Filed under: ,

Here I got the exact word and its meaning for the work what I or all degelopers use to do after completion of each module/integration. Smoke testing / build verification testing is done by developers before the build is released or by testers before accepting a build for further testing. In this sense a smoke test is the process of validating code changes before the changes are checked into the larger product’s official source code collection (VSS).

This is a "shallow and wide" approach to the application. The tester "touches" all areas of the application without getting too deep, looking for answers to basic questions like, "Can I launch the test item at all?", "Does it open to a window?", "Do the buttons on the window do things?".

There is no need to get down to field validation or business flows. If you get a "No" answer to basic questions like these, then the application is so badly broken, there's effectively nothing there to allow further testing.

These written tests can either be performed manually or using an automated tool. When automated tools are used, the tests are often initiated by the same process that generates the build itself.

This is sometimes referred to as 'rattle' testing - as in 'if I shake it does it rattle?'.

Multiple Active Result Sets (MARS) is a feature in ADO.NET 2.0. It allows execution of multiple batches against Database on a single connection. Preeviously, only one batch could be executed at a time against a single connection. But, execution of multiple batches with MARS does not mean like simultaneous execution of operations.
In previous versions of SQL Server; to access multiple result sets using SqlDataReader objects, a separate SqlConnection object must be used with each SqlCommand object. In ADO.NET 2.0 / SQL Server 2005; MARS feature is disabled by default. It can be enabled by adding the "MultipleActiveResultSets=True" keyword pair to your connection string, as below:

string connectionString = @"Data Source=GTL-263\SQLEXPRESS;Initial Catalog=master;Integrated Security=SSPI;MultipleActiveResultSets=True";

Example:

Without MARS, you could only run one batch per connection. some what like below Example:

private void NoMarsImplementation()
{
    SqlConnection conn = new SqlConnection(@"Data Source=GTL-263\SQLEXPRESS;
    Initial Catalog=master;Integrated Security=SSPI;");

    string sql1 = "SELECT * FROM [Customer].[TBL_Customer]";
    string sql2 = "SELECT * FROM [Supplier].[TBL_Supplier]";

    SqlCommand cmd1 = new SqlCommand(sql1, conn);
    SqlCommand cmd2 = new SqlCommand(sql2, conn);
    cmd1.CommandTimeout = 500;
    cmd2.CommandTimeout = 500;
    conn.Open();
    SqlDataReader dr1 = cmd1.ExecuteReader();
    // misc. code with dr1
    conn.Close();

    conn.Open();
    SqlDataReader dr2 = cmd2.ExecuteReader();
    // misc. code with dr2
    conn.Close();
}

Above Example shows that you can use the same connection with the second SqlDataReader only when you finished using the connection with first one. The connection must be closed and reopened to use same Connection with Second SqlDataReader. Otherwise you would get this error - "There is already an open DataReader associated with this Command which must be closed first".

with MARS, it is possible to use a single opened connection for more than one batch. Check out below code:

private void MarsImplementation()
{
    SqlConnection conn = new SqlConnection(@"Data Source=GTL-263\SQLEXPRESS;
    Initial Catalog=master;Integrated Security=SSPI;MultipleActiveResultSets=true;");

    string sql1 = "SELECT * FROM [Customer].[TBL_Customer]";
    string sql2 = "SELECT * FROM [Supplier].[TBL_Supplier]";

    SqlCommand cmd1 = new SqlCommand(sql1, conn);
    SqlCommand cmd2 = new SqlCommand(sql2, conn);
    cmd1.CommandTimeout = 500;
    cmd2.CommandTimeout = 500;
    conn.Open();
    SqlDataReader dr1 = cmd1.ExecuteReader();
    // misc. code with dr1
    SqlDataReader dr2 = cmd2.ExecuteReader();
    // misc. code with dr2
    conn.Close();
}

In this way, using MARS, you can simply execute an SqlDataReader that will open a Read-Only Cursor; use data from that SqlDataReader and perform Insert / Update function against Database. You only need to Open the SqlConnection object once before you execure the SqlDataReader and Close the Connection (without re-openning) at last after performing Insert / Update function.

Here is another Example, in which we retrieve records from Category Table which is having ParentCategoryID as 0 thru SqlDataReader and Update the Product Table records which is having CategoryID from SqlDataReader.

    private void MarsImplementation()
    {
        //connection string
        string connectionString = @"Data Source=GTL-263\SQLEXPRESS;Initial Catalog=master;
        Integrated Security=SSPI;MultipleActiveResultSets=true;";
        
        SqlTransaction updateTran = null;
        //sqlCommand to open SqlDataReader
        SqlCommand catCmd = null;
        //sqlCommand to update the Product table
        SqlCommand updateCmd = null;

        int CategoryID = 0;

        //Query to fetch the categories with ParentCategoryID having 0
        string catSQL =
            "SELECT CategoryID, Name FROM Category " +
            "WHERE ParentCategoryID = 0";

        //update all the product's quantity which is having CategoryID from above Query
        string updateSQL =
            "UPDATE Product " +
            "SET Qty = Qty + @OrderQty " +
            "WHERE CategoryID = @CategoryID";

        using (SqlConnection Connection =
          new SqlConnection(connectionString))
        {
            Connection.Open(); //open the connection once here
            updateTran = Connection.BeginTransaction();

            catCmd = new SqlCommand(catSQL, Connection);
            catCmd.Transaction = updateTran;

            updateCmd = new SqlCommand(updateSQL, Connection);
            updateCmd.Transaction = updateTran;
            updateCmd.Parameters.Add("@Qty", SqlDbType.Int);
            updateCmd.Parameters.Add("@ProductID", SqlDbType.Int);

            //execute the sqlDataReader
            using (SqlDataReader catReader = catCmd.ExecuteReader())
            {
                while (catReader.Read())
                {
                    CategoryID = (int)catReader["CategoryID"];

                    updateCmd.Parameters["@OrderQty"].Value = 100;
                    updateCmd.Parameters["@CategoryID"].Value = CategoryID;                    
                    //perform Update against Product table with same connection
                    //without closing and re-openning it again
                    //having SqlDataReader already openned
                    updateCmd.ExecuteNonQuery();
                }
            }
            updateTran.Commit();            
        }

    }

Posted by kaushalparik | 4 comment(s)
Filed under: , ,

Below, is the JavaScript code function snippet I used in one of my web application; to provide the functionality of "Select All Child" when ParentNode CheckBox is Checked; means to automatically Check all the ChildNode CheckBoxes, when you Check the ParentNode. I used the TreeView Control with ShowCheckBoxes Property.

    <script type="text/javascript" language="javascript">
    function SelectAllChildNodes()
    {
        //debugger;
        var obj = window.event.srcElement;
        var treeNodeFound = false;

        var checkedState;
        if (obj.tagName == "INPUT" && obj.type == "checkbox")
        {
            var treeNode = obj;
            checkedState = treeNode.checked;
            do
            {
                obj = obj.parentElement;
            } while (obj.tagName != "TABLE")
            
            var parentTreeLevel = obj.rows[0].cells.length;            
            var parentTreeNode = obj.rows[0].cells[0];
            var tables = obj.parentElement.getElementsByTagName("TABLE");
            var numTables = tables.length;
            if (numTables >= 1)
            {
                for (iCount=0; iCount < numTables; iCount++)
                {
                    if (tables[iCount] == obj)
                    {
                        treeNodeFound = true;
                        iCount++;
                        if (iCount == numTables)
                        {
                            return;
                        }
                    }
                    if (treeNodeFound == true)
                    {
                        var childTreeLevel = tables[iCount].rows[0].cells.length;
                        if (childTreeLevel > parentTreeLevel)
                        {
                            var cell = tables[iCount].rows[0].cells[childTreeLevel - 1];
                            var inputs = cell.getElementsByTagName("INPUT");
                            inputs[0].checked = checkedState;
                        }
                        else
                        {
                            return;
                        }
                    }
                }
            }
        }
    }
    </script>

Finally, call the function in "onClick" event of TreeView Control as,

        <asp:TreeView ID="TreeView1" runat="server" ShowCheckBoxes="All" onclick="SelectAllChildNodes()">
            <Nodes>
                <%--TreeView Nodes--%>
            </Nodes>
        </asp:TreeView>

Hope it may help to whom want to achieve this common functionality using TreeView.

Posted by kaushalparik | 2 comment(s)
Filed under: ,


Have you ever wanted to clear or remove unwanted items from your "Recent Projects" list on your Visual Studio 2008/2005 startup page?
Here is an nice tip on how to clear the "Recent Project" list:

Close Visual Studio (if its open)

    GOTO > Start > Run > RegEdit

    GOTO > HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\<version>\ProjectMRUList
    remove unnecessary items from list.

    Similarly repeat the steps for FileMRuList
    GOTO > HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\<version>\FileMRUList
    remove unnecessary items from list.

    To Clear the Find and Replace List
    GOTO > HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\<version>\Find
    remove unnecessary items from list.

Another Simple way is,
    Create one Text file "Clear.txt" and add below contents in it

    Windows Registry Editor Version 5.00

    [-HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0\ProjectMRUList]
    [HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0\ProjectMRUList]

    Save and Close the file and rename is as "Clear.reg"; that is Registry file. Double Click to Run the file, this will clear the "Recent Project List" on your Visual Studio 2005 Startup Page. You can add entries for "Recent File List" and "Find and Replace List" in this same .reg file.

 

Posted by kaushalparik | 4 comment(s)
Filed under:

The Repeater control is the only Web control that allows you to split markup tags across the templates. To create a table using templates, include the begin table tag (<table>) in the HeaderTemplate, a single table row tag (<tr>) in the ItemTemplate, and the end table tag (</table>) in the FooterTemplate.

Example:

<asp:Repeater id=Repeater1 runat="server">
    <HeaderTemplate>
        <TABLE border=1 id="table1">
        <THEAD>
        <tr>
           <th><b>Column1</b></th>
           <th><b>Column2</b></th>
        </tr>
        </THEAD>
        <TBODY>
    </HeaderTemplate>

    <ItemTemplate>
        <tr>
        <td> <%# DataBinder.Eval(Container.DataItem, "XXXX") %> </td>
        <td> <%# DataBinder.Eval(Container.DataItem, "XXXX") %> </td>
        </tr>
    </ItemTemplate>

    <FooterTemplate>
        </TBODY>
        </TABLE>
    </FooterTemplate>
</asp:Repeater>

 

Posted by kaushalparik | 1 comment(s)
Filed under: ,

The "Mode" Property of Literal Control specifies an enumeration value that decides how the content in the Literal control is rendered
This property is set using one of the LiteralMode enumeration values. The following lists the possible values:

1. PassThrough: The contents of the control are not modified.
2. Encode: The contents of the control are converted to an HTML-encoded string.
3. Transform: Unsupported markup-language elements are removed from the contents of the control. If the Literal control is rendered on a browser that supports HTML or XHTML, the control's contents are not modified.

If you specify PassThrough, the entire contents of the Text property are passed to the device or browser without making any modifications. For example, if the Text property of a Literal control contains an <hr> tag, it is sent to all devices and browsers whether it is supported or not.

If you specify Encode, the contents for the Text property are converted into an HTML-encoded string before rendering. For example, if the Text property of a Literal control contains an <hr> tag, it is converted to &lt;Hr&gt; and sent to the device or browser.

If you specify Transform, the unsupported markup elements will be removed. In this case, any markup language elements of the Text property that are not supported in the targeted markup language are not rendered for the control. For example, if an unsupported tag contains content, only the tag is removed and the content is sent to the device or browser. For example, if the Text property contains the content <XYZ>Test</XYZ>, the <XYZ> and </XYZ> tags are removed, and the text "Test" is sent to the device or browser.

Example:

    PassThrough: Entire content in the Text Property of Literal will be parsed and rendered in Browser without any modification.
    <asp:Literal
        id="ltlFirst"
        Mode="PassThrough"
        Text="<hr />"
        Runat="server" />

    Encode: Entire content in the Text Property of Literal will be converted into HTML-encoded string.
    <asp:Literal
        id="ltlSecond"
        Mode="Encode"
        Text="<hr />"
        Runat="server" />

    Transform: Entire content in the Text Property of Literal will be redered after removing unsupported elements.
    <asp:Literal
        id="ltlThird"
        Mode="Transform"
        Text="<XYZ><hr /></XYZ>"
        Runat="server" />

 

Posted by kaushalparik | 105 comment(s)
Filed under: ,

        Now-a-Days, I am working on a project that is developed priorly in Delphi and needs to be re-developed and enhanced in .NET Technology. We dont have any standard Docs or Help files like ReadMe; so understanding the application by reading / reviewing the Code and Database. Meantime, I came accross this word "Reverse engineering".
        Reverse engineering is the process of analyzing a subject system to create representations of the system at a higher level of abstraction. It can also be seen as "going backwards through the development cycle". In this model, the output of the implementation phase (in source code form) is reverse engineered back to the analysis phase, in an inversion of the traditional waterfall model. Reverse engineering is a process of examination only: the software system under consideration is not modified. Reverse engineering often is done because the documentation of application or any of module has been lost (or was never written), and the person who built the widget is no longer available.
        Other purposes of reverse engineering include security auditing, removal of copy protection ("cracking"), circumvention of access restrictions often present in consumer electronics, customization of embedded systems (such as engine management systems), in-house repairs or retrofits, enabling of additional features on low-cost "crippled" hardware (such as some graphics card chipsets), or even mere satisfaction of curiosity.

Compound Assignment Operators in SQL Server 2008 

Compound assignment operator means an operator combined with another operator. We have used such assignment operators in C++ and C#. This Compound Assignment Operator is introduced in SQL Server 2008.

 

The compound assignment operators; supported in SQL Server 2008 are:

 

Compound Assignment

Operator

Description
+= Add and assign
-= Subtract and assign
*= Multiply and assign
/= Divide and assign
%= Modulus and assign
&= Bitwise AND and assign
|= Bitwise OR and assign
^= Bitwise XOR and assign

 

Compound Assignment Operator - Add and Assign Example:

 

Declare @Compvar int
Set @Compvar = 3
--using Compound assignment operator
Set @Compvar+=7
Select @ Compvar as CompResult
Go

Output will be

MyResult
10
(1 row(s) affected)

In the above example, the compound assignment operator added the value 7 to the existing value of the variable @Compvar and assigned the resulting value to @Compvar.

Posted by kaushalparik | 10 comment(s)
Filed under:

 

Recently I tried AutoComplete extender (AJAX toolkit) in one of my on going web application. What I suppose to do is, user shall be able to get the AutoSense list of available products from database on typing the name of the product in a TextBox. When user types some letters in the Textbox, a popup panel will come to action and displayed the related words. So that the user can choose exact word from the popup panel. BTW, Ajax extension and Ajax Tool Kit should already be installed to implement any AJAX extenders. Here are the steps how to accomplish an AutoComplete TextBox from Database:

 

  • We start by creating new website. Create a new website by selecting “ASP.NET AJAX-Enabled Web Site” from installed templates in “New Web Site” window.

  • ScriptManager” would already be there in your webpage (Default.aspx), as we have selected AJAX Enabled Website.

  • Now drag and drop a Textbox from your Toolbox and AutoCompleteExtender to your webpage.

  • Then add a webservice to your project as WebService.asmx.

  • First of all, you need to Import “System.Web.Script.Services” namespace and add the “ScriptService” reference to the webserive.

  • Next, just need to write a simple webmethod ‘GetProducts’ to fetch the data from the Product table which will return the string array with product names.

  • We will pass the “PrefixText” to this webmethod; I mean the characters that are typed by the user in the textbox to get the exact AutoComplete Product list form Database that start with the characters typed by the user.

  • Here is the complete webmethod for that:

        using System;
        using System.Configuration;
        using System.Data;
        using System.Data.SqlClient;
        using System.Web;
        using System.Collections;
        using System.Web.Services;
        using System.Web.Services.Protocols;
        using System.Web.Script.Services;

        /// <summary>
        /// Summary description for WebService
        /// </summary>
        [ScriptService]
        [WebService(Namespace = "http://tempuri.org/")]
        [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
        public class WebService : System.Web.Services.WebService
        {
            public WebService()
            {
                //Uncomment the following line if using designed components
                //InitializeComponent();
            }        
            [WebMethod]
            public string[] GetProducts(string prefixText)
            {
            string sql = "Select * from product Where name like @prefixText";
            SqlDataAdapter da = new SqlDataAdapter(sql, ConfigurationManager.AppSettings["DBConn"]);
            da.SelectCommand.Parameters.Add("@prefixText", SqlDbType.VarChar, 50).Value = prefixText + "%";
            DataTable dt = new DataTable();
            da.Fill(dt);
            string[] items = new string[dt.Rows.Count];
            int i = 0;
            foreach (DataRow dr in dt.Rows)
            {
                items.SetValue(dr["name"].ToString(), i);
                i++;
            }
            return items;
           }
        }

 

  • you can see that we have passed prefixText as argument in above webmethod , which sends it to the query to fetch only the related words that starts with the prefixText values. Then it returns the result as an array of strings.

  • In the your webpage, set the AutoCompleteExtender’s TargetControlID property to the TextBox Id. You also need to set ServicePath property as WebService.asmx, ServiceMethod as GetProducts and MinimimPrefixLength as 1.

  • So, your web page design code will be something like:

    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server" />
        <div>
            <asp:TextBox ID="TextBox1" runat="server" Width="785px"></asp:TextBox>
            <cc1:AutoCompleteExtender ID="AutoCompleteExtender1" runat="server" MinimumPrefixLength="1" ServiceMethod="GetProducts" ServicePath="WebService.asmx" TargetControlID="TextBox1">
            </cc1:AutoCompleteExtender>
        </div>
    </form>

Thats it! Quite simple and a useful feature that user would like to have. Find the sample Code available to Download in attechment.

 

 

 

 

Eventhough DataTableReader is an excellent concept and got lot of advantages when compared to SqlDataReader, it is not yet widely used in web application development. Even I have never used the DataTableReader Class in any of my application before. But, the combination of DataTable + DataReader (I.e. connected + disconnected architecture) is the most impressive thing about DataTableReader.


Connected and disconnected architecture:


ADO.NET supports two different programming environments: connected and disconnected.


The connected environment provides forward-only, read-only access to data in the data source and the ability to execute commands against the data source. The connected classes provide a common way to work with connected data regardless of the underlying data source. They include Connection, Command, DataReader, Transaction, ParameterCollection, and Parameter classes.


The disconnected environment allows data retrieved from the data source to be manipulated and later reconciled with the data source. The disconnected classes provide a common way to work with disconnected data regardless of the underlying data source. They include the DataSet, DataTable, DataColumn, DataRow, Constraint, DataRelationship, and DataView classes.


DataReader:


As we know; DataReader supports connected architecture and provides connected forward-only, read-only access to the data source. It is optimized for speed. The DataReader is instantiated through a Command object.


DataTable:


DataTable allows disconnected data to be examined and modified through a collection of DataColumn and DataRow classes. The DataTable allows constraints such as foreign keys and unique constraints to be defined using the Constraint class.


DataTableReader:


SqlDataReader are much faster than DataSet and consume less memory. But the major drawback of using SqlDataReader is that it always required an open connection to operate, that is, it is connection oriented. Hence we needed to explicitly close the database connections when we were done using it.

DataTableReader class has been developed similar to it but with one exception – it works in a disconnected mode. Clearly opening and closing of database server connection is taken care by the DataTableReader itself. The iteration of rows is done from the cache. The cached data can be modified while the DataTableReader is active, and the reader automatically maintains its position.

A simple DataTableReader:


DataTableReader can be created from any DataTable’s CreateDataReader method. Check out the Example below to create a DataTableReader.


private void CreateDataTableReader()
{
  string sql = "Select * from Product";
  SqlDataAdapter da = new SqlDataAdapter(sql,”ConnectionString”);
  DataTable dt = new DataTable(); da.Fill(dt);
  DataTableReader dtr = dt.CreateDataReader();
  if (dtr.HasRows)
  {
   while (dtr.Read())
   {
    Response.Write(dtr[“ProductName”].ToString() + "<br/>");
   }
  }
  else
   Response.Write("No Records");
}


A DataTableReader with more than one DataTables:


One of the nice features of DataTableReader is that it can contain more than one DataTables, as read-only and forward-only recordsets. When you load more than one DataTables in a DataTableReader, it is really faster to iterate and it will automatically deals with the unwanted records during the iteration. You can load bunches of DataTables by creating an object of DataTableReader to contain an array of DataTables.


private void CreateDataTableReader()
{
 string sql = "Select * from Product";
 SqlDataAdapter da = new SqlDataAdapter(sql,”ConnectionString”);
 DataTable dtProduct = new DataTable();
 da.Fill(dtProduct);

 string sql1 = "Select * from Category";
 SqlDataAdapter da1 = new SqlDataAdapter(sql1,”ConnectionString”);
 DataTable dtCat = new DataTable();
 da1.Fill(dtCat);

 DataTableReader dtr = new DataTableReader(new DataTable[] {dtProduct, dtCat});
 if (dtr.HasRows)
 {
  do
  {
   while (dtr.Read())
   {
    Response.Write(dtr[1].ToString() + "<br/>");
   }
  } while (dtr.NextResult());
 }
 else
  Response.Write("No Records");
}


Summary:


The DataTableReader works much like any other data reader, such as the SqlDataReader, except that the DataTableReader provides for iterating over rows in a DataTable. In other words, it provides for iterating over rows in a cache. The cached data can be modified while the DataTableReader is active, and the reader automatically maintains its position.


When you create a DataTableReader from a DataTable, the resulting DataTableReader object contains one result set with the same data as the DataTable from which it was created, except for any rows that have been marked as deleted. The columns appear in the same order as in the original DataTable. The structure of the returned result is identical in schema and data to the original DataTable. A DataTableReader that was created by calling the GetDataReader() method of a DataSet object contains multiple result sets if the DataSetcontains more than one table. The results are in the same sequence as the DataTableobjects in the DataTableCollection of the DataSet object.


Reference:


DataTableReader Class (System.Data)

 

Posted by kaushalparik | 1 comment(s)
Filed under: ,