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();
}
}
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();
}
}
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.
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.
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>
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 <Hr> 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" />
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.
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)