<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-864116869953733620</id><updated>2012-02-16T19:43:44.841-08:00</updated><category term='ASP.Net Perfromance'/><category term='.Net-Interview'/><category term='DataTables'/><category term='DataGrid'/><category term='Master Pages'/><category term='Dataset'/><category term='Multithreading'/><category term='WCF'/><category term='Secure web applications'/><category term='SQL Interview Questions'/><category term='C#Interview'/><title type='text'>Amit Narula's Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://narulaamitsk.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://narulaamitsk.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Amit Narula</name><uri>http://www.blogger.com/profile/03373886236261160868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_KIFo2nRsLTc/SfIq-GgjUkI/AAAAAAAACCo/bBDItRMEB6s/S220/DSCF1775.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>20</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-864116869953733620.post-1832363972737430456</id><published>2009-07-13T11:42:00.000-07:00</published><updated>2009-07-13T11:45:04.926-07:00</updated><title type='text'>Requirement Gathering Tips for designing successfull software architecture</title><content type='html'>&lt;div style="text-align: justify;"&gt;Software requirements analysis is critical to the success of a software project. Inappropriate gathering of software requirements is a major reason for projects not achieving the desired results. A META group research indicates that approximately 60-70 percent of IT project failures occur directly as a result of poor gathering of requirements, analysis, and management. Unclear requirements often increase the tendency amongst software designers and architects to over-engineer the solution. Here we will take a look at the ‘software over-engineering trap’ and the ways to avoid it.&lt;br /&gt;&lt;br /&gt;In a recent recovery project, we were called to ‘fix’ the software developed by the customer’s own team. The testing team found that the software, though claimed to be highly scalable, was too slow and unresponsive, especially on smaller number of users. On investigating, we found that though the software architecture used the most fanciful technologies, implemented nifty design principles, and seemed ‘perfect’, it did not work when deployed. This is a classic example of what I call the ‘software over-engineering trap’. Let us take a closer look at why we fall into this trap.&lt;br /&gt;&lt;br /&gt;Top Reasons for Getting into the ‘Over-engineering’ Trap&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;1. Lust for using latest technologies:&lt;/span&gt; Being abreast of all latest technologies available in the market, it is natural for software architects to have an inclination to use them. But in the eagerness to use the latest technologies, one should not lose sight of whether it is actually required for the project at hand.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2.   Lack of clarity on non-functional requirements:&lt;/b&gt; Often the customer is not able to convey the requirements in the best possible way and may also be not sure on the levels of performance and scalability required. In such situations, the software architects may tend to take the safest route: create a software architecture that is straight from the textbook.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;3.   Limited understanding of technology at client-side:&lt;/b&gt; Customers may not always have a tech-savvy member working directly with them to objectively review what the architects produce.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;4.   Background of the architects or designers:&lt;/b&gt; Many times, architects play on their strength. They propose what they know the best.&lt;br /&gt;&lt;br /&gt;All problems have a solution. We can avoid the trap, by enforcing some simple and effective steps. I call them ‘powers’ and I believe in them as if they were God sent. Nothing fanciful, but they really work.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Power of Non-functional Requirements&lt;/b&gt;&lt;br /&gt;In contrast to the functional requirements that determine how the system would behave, non-functional requirements (NFRs - that specify things like performance, scalability, and security requirements) are more intangible and ambiguity prone. But they are critical to the overall success of the software project and can dominate the design and architectural decision. Unfortunately, we tend not to give them their due importance because of the reasons discussed earlier. Both customers and analysts are very good at capturing functional requirements, but capturing non-functional requirements is not as easy. In many projects, NFRs are either not defined or defined very vaguely with fancy sounding open statements or defined very late in the game, almost after the software has been developed. Thanks to Mr. Murphy, the process of capturing non-functional requirements is paved with unusually high number of hurdles and speed-breakers. The end result is that we ignore the NFRs and move ahead in order to avoid delays in the project.&lt;br /&gt;&lt;br /&gt;For example, if the customer has minimal scalability requirements, then one must carefully evaluate the need of service-orientedness (assuming no other pressing need for service orientation exists). In our recovery project example, we found that the scalability requirements were not captured properly. In reality, the customer had very minimal scalability requirements, but due to unclear requirements the designers ended up designing a highly scalable multi-layered service oriented system. As a result the system became too slow when deployed in production environments. Most architects know that each design decision comes with a trade-off and clarity in non-functional requirements help us make that decision meaningful to the customer situation.&lt;br /&gt;&lt;br /&gt;Here are some guidelines that, when followed, can help us exploit the power of NFRs and make our architecture much closer to the real customer requirements:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1.   Make NFRs non-negotiable:&lt;/b&gt; Irrespective of how many hurdles you may face in gathering accurate NFRs, one rule I always follow is to define a clear ‘must-achieve’ milestone by which the customer must give you all non-functional and operational requirements before the team moves to the coding phase. No sign off on NFRs, no movement in the project.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;2.   Document NFRs in the form of data:&lt;/b&gt; Document NFRs in the form of real numbers and not as open statements. For example, rather than saying, “The new system must be as good in performance as the legacy system,” one must get customers to give data in the forms such as - ‘the new system must load in less than 1 second’ or ‘the search page must provide all matching employee records in no more than 3 seconds’. Adopt this data-centric approach for scalability, installation, performance, security, and other non-functional requirements.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;3.   Focus on deployment:&lt;/b&gt; Look at the way the customer is going to deploy the software after you develop. Would it be deployed on one machine, or multiple servers, or a cluster of machines? Get an agreement on the physical deployment of the software early in the game. I particularly recommend that each team member prints the physical deployment diagram and pins it up on his or her desk.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;4.   Data flow diagrams and threat modeling for security:&lt;/b&gt; Look at the security aspect very carefully. What level of security is needed? Which portions of the system should be more secure than the others? What access levels and permissions you must provide to various roles that exist in the application? I found preparing a basic ‘data flow diagram’ very helpful in determining what type of security is needed at each level of the software. Using this simple data flow diagram, it’s very easy to figure out where a customer is exchanging personal information that requires higher security versus normal information. Many architects also perform what is known as ‘threat modeling’ based on such diagrams and other inputs before proceeding ahead with design.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Power of Traceability Matrix&lt;/b&gt;&lt;br /&gt;The capability to map the requirements increases the likelihood of delivering a software product that fulfills the customer’s needs. Using a ‘traceability matrix’ for this purpose is highly recommended. Most likely, you may have heard about this many times before. However, the simple submission here is that most companies either do a mere lip service to it or prepare this matrix in later phases of the lifecycle.&lt;br /&gt;&lt;br /&gt;When used right from the start, this matrix helps us trace back the architectural considerations to real customer needs. Whether the customer asked you to prepare a traceability matrix or not, you should do it in your own interest. In this matrix, one would write down specific aspects of the architecture like componentization, service-oriented-ness, configurability, and dynamic discovery and map them to the customer requirement, especially the NFRs captured earlier. In the next column, one would also write what the drawback of using each of these architectural considerations is. In the end, you would write down what type of hardware and deployment environment would be needed for this design to deliver results. Once complete, this helps us to re-consider our design in the event it is not mapping to any customer requirement, or is having more negatives than positives. Or, if the hardware needed is much more demanding than what the customer is going to use.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Power of Demonstrations&lt;/b&gt;&lt;br /&gt;As they say, ‘the proof of the pudding is in eating’. And the proof of your software architecture is after you see it running live to your total satisfaction! In addition to delivering software in optimally frequent intervals, you will particularly find the concept of creating ‘min-deployment lab’ very useful. This lab mimics the real deployment environment that customer has signed up for. It has the same firewall, DMZ, domain, and security settings as the real environment would. This environment is first used by developers and testers to deploy the system and perform the testing before releasing the software. Later, the same deployment lab can be used by the customer’s teams for phase-end demonstrations. A small investment in such labs gives great ROI, as compared with the cost of fixing failed projects. Your development teams would be surprised to see your own system not behaving as intended or even crashing when really deployed in this mini-lab. This would help them solve some critical deployment level defects early in the game. If setting up a lab at the development location is not always feasible, then the project teams must look at using the customer staging and testing environments during the development cycles.&lt;br /&gt;&lt;br /&gt;In today’s environment, with the advancements in development, deployment, and virtualization tools, setting up this lab has become easier than ever before. Teams that follow agile software development methodologies can conduct phase-end demonstrations of functional and non-functional requirements in this mini-lab to avoid unpleasant surprises in the end.&lt;br /&gt;&lt;br /&gt;So here’s to real IT that works for the customer, and for you!&lt;br /&gt;&lt;br /&gt;Implementing these methodological and effective approaches to software requirements gathering helps the architects collect, segregate, prioritize, analyze, and document all the relevant informational and process needs for the application under design. This understanding of software requirements gathering will help give you a competitive edge over others.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/864116869953733620-1832363972737430456?l=narulaamitsk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://narulaamitsk.blogspot.com/feeds/1832363972737430456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=864116869953733620&amp;postID=1832363972737430456' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/1832363972737430456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/1832363972737430456'/><link rel='alternate' type='text/html' href='http://narulaamitsk.blogspot.com/2009/07/requirement-gathering-tips-for.html' title='Requirement Gathering Tips for designing successfull software architecture'/><author><name>Amit Narula</name><uri>http://www.blogger.com/profile/03373886236261160868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_KIFo2nRsLTc/SfIq-GgjUkI/AAAAAAAACCo/bBDItRMEB6s/S220/DSCF1775.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-864116869953733620.post-2624548266030658910</id><published>2009-07-05T00:24:00.000-07:00</published><updated>2009-07-05T00:38:09.087-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>Calling a WCF service from Javascript</title><content type='html'>In this sample I presume you can use Visual Studio 2008 and know a little about WCF.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;1. Create an empty solution, and add a WCF service library to it&lt;/span&gt;&lt;br /&gt;We'll call the solution JSONWCFTest, and the library JSONServices.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;2. Add a data contract&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;using System.Collections.Generic;&lt;br /&gt;using System.Runtime.Serialization;&lt;br /&gt;&lt;br /&gt;namespace JSONServices&lt;br /&gt;{&lt;br /&gt;  [DataContract]&lt;br /&gt;  public class SampleDataObject&lt;br /&gt;  {&lt;br /&gt;      public SampleDataObject(int NewId, string NewName)&lt;br /&gt;      {&lt;br /&gt;          Id = NewId;&lt;br /&gt;         Name = NewName;&lt;br /&gt;      }&lt;br /&gt;      [DataMember]&lt;br /&gt;      public int Id { get; set; }&lt;br /&gt;&lt;br /&gt;      [DataMember]&lt;br /&gt;      public string Name { get; set; }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;3. Add an implementing class&lt;/span&gt;&lt;br /&gt;Implement the data contract like this&lt;pre&gt;using System.Collections.Generic;&lt;br /&gt;&lt;br /&gt;namespace JSONServices&lt;br /&gt;{&lt;br /&gt;  public class JSONService : IJSONService&lt;br /&gt;  {&lt;br /&gt;      public SampleDataObject GetSingleObject(int id, string name)&lt;br /&gt;      {&lt;br /&gt;          return new SampleDataObject(id, name);&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      public ICollection&lt;sampledataobject&gt; GetMultipleObjects(int number)&lt;br /&gt;      {&lt;br /&gt;          List&lt;sampledataobject&gt; list = new List&lt;sampledataobject&gt;();&lt;br /&gt;          for (int i = 0; i &lt; number; i++)          &lt;br /&gt;              { &lt;br /&gt;                  list.Add(new SampleDataObject(i, "Name" + i));       &lt;br /&gt;              }           &lt;br /&gt;          return list;       &lt;br /&gt;      }   &lt;br /&gt;   }&lt;br /&gt;} &lt;/sampledataobject&gt;&lt;/sampledataobject&gt;&lt;/sampledataobject&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;4. Add an operation contract&lt;/span&gt;&lt;br /&gt;Add an interface IJSONService with the following methods&lt;br /&gt;&lt;pre&gt;using System.Collections.Generic;&lt;br /&gt;using System.ServiceModel;&lt;br /&gt;&lt;br /&gt;namespace JSONServices&lt;br /&gt;{&lt;br /&gt;  [ServiceContract(Namespace="http://DotNetByExample/JSONDemoService")]&lt;br /&gt;  public interface IJSONService&lt;br /&gt;  {&lt;br /&gt;      [OperationContract]&lt;br /&gt;      SampleDataObject GetSingleObject(int id, string name);&lt;br /&gt;&lt;br /&gt;      [OperationContract]&lt;br /&gt;      ICollection&lt;sampledataobject&gt; GetMultipleObjects(int number);&lt;br /&gt; }&lt;br /&gt;}&lt;/sampledataobject&gt;&lt;/pre&gt;So far, this is very basic WCF stuff. Nothing special here.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;5. Add new web application&lt;/span&gt;&lt;br /&gt;Add a new project of type "ASP.NET Web Application" to the solution. Call it JSONTestApp.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;6. Add a SVC file to the web application&lt;/span&gt;&lt;br /&gt;This part is a bit awkward. Choose "Text File", and name it "AjaxService.svc". Then open the file, and enter the following code&lt;pre&gt;&lt;%@ServiceHost    language="C#"    Debug="true"   &lt;br /&gt;Service="JSONServices.JSONService"   &lt;br /&gt;Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" %&amp;gt;&lt;/pre&gt;It may be tempting to add an "Ajax-enabled WCF service" to the project but this creates its own operation contract, and in this example I want to simulate the situation in which I re-use an already existing operation contract implemented in a separate service library.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;7. Check the javascript interface&lt;/span&gt;&lt;br /&gt;Basically, you are done now. Your service is hosted callable from javascript. You can check right-clicking on AjaxService.svc, and you will now see a web page that will say something like "This is a Windows© Communication Foundation service.&lt;br /&gt;Metadata publishing for this service is currently disabled." and a lot things more. You can check the javascript interface by adding "/jsdebug" to the url displayed in your browser, in my case this is "http://localhost:1781/AjaxService.svc/jsdebug". This shows the dynamically generated javascript proxy that you can call in your client code:&lt;pre&gt;Type.registerNamespace('dotnetbyexample.JSONDemoService');&lt;br /&gt;dotnetbyexample.JSONDemoService.IJSONService=function() {&lt;br /&gt;dotnetbyexample.JSONDemoService.IJSONService.initializeBase(this);&lt;br /&gt;this._timeout = 0;&lt;br /&gt;this._userContext = null;&lt;br /&gt;this._succeeded = null;&lt;br /&gt;this._failed = null;&lt;br /&gt;}&lt;br /&gt;&lt;span style="color:red;"&gt;dotnetbyexample.JSONDemoService.IJSONService&lt;/span&gt;.prototype={&lt;br /&gt;_get_path:function() {&lt;br /&gt;var p = this.get_path();&lt;br /&gt;if (p) return p;&lt;br /&gt;else return dotnetbyexample.JSONDemoService.IJSONService._staticInstance.get_path();}&lt;br /&gt;,&lt;span style="color:red;"&gt;GetSingleObject&lt;/span&gt;:function(id,name,succeededCallback, failedCallback, userContext) {&lt;br /&gt;/// &amp;lt;param name="id" type="Number"&amp;gt;System.Int32&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name="name" type="String"&amp;gt;System.String&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name="succeededCallback" type="Function" optional="true"&lt;br /&gt;mayBeNull="true"&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name="failedCallback" type="Function" optional="true"&lt;br /&gt;mayBeNull="true"&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name="userContext" optional="true" mayBeNull="true"&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;return this._invoke(this._get_path(), 'GetSingleObject',false,{id:id,name:name},&lt;br /&gt;succeededCallback,failedCallback,userContext); },&lt;br /&gt;&lt;span style="color:red;"&gt;GetMultipleObjects&lt;/span&gt;:function(number,succeededCallback, failedCallback, userContext) {&lt;br /&gt;/// &amp;lt;param name="number" type="Number"&amp;gt;System.Int32&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name="succeededCallback" type="Function" optional="true"&lt;br /&gt; mayBeNull="true"&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name="failedCallback" type="Function" optional="true"&lt;br /&gt;TomayBeNull="true"&amp;gt;&amp;lt;/param&amp;gt;&lt;br /&gt;/// &amp;lt;param name="userContext" optional="true" mayBeNull="true"&amp;gt;&amp;lt;/param&amp;gt;&lt;/pre&gt;As you can see this contains a lot of plumbing - and this is only the top part - but I emphasized the parts that are interesting right now: the name of the object that you need to call from javascript (dotnetbyexample.JSONDemoService.IJSONService) and the methods, which are - surprise, suprise - have exactly the same name as their C# server-side counterparts. From here on, the procedure is pretty much the same as we were used to when calling asmx webservices from javascript:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;8. Add an Web Form to the Web Application&lt;/span&gt;&lt;br /&gt;Call it TestForm1.aspx&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;9. Add a script manager and a reference&lt;/span&gt;&lt;br /&gt;Add a script manager to the form, right below the form tag, and make a reference to the AjaxService.svc file:&lt;pre&gt;&amp;lt;form id="form1" runat="server"&amp;gt;&lt;br /&gt;&amp;lt;asp:scriptmanager runat="server"&amp;gt;&lt;br /&gt;&amp;lt;services&amp;gt;&lt;br /&gt;  &amp;lt;asp:ServiceReference Path="AjaxService.svc" /&amp;gt;&lt;br /&gt;&amp;lt;/services&amp;gt;&lt;br /&gt;&amp;lt;/asp:scriptmanager&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;10. Add some user interface elements to call the service&lt;/span&gt;&lt;br /&gt;Right below the script reference, add the following code:&lt;pre&gt;&amp;lt;div&amp;gt;&lt;br /&gt;   ID&amp;lt;asp:TextBox ID="tbId" runat="server"&amp;gt;21&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;   Name&amp;lt;asp:TextBox ID="tbName" runat="server"&amp;gt;John Doe&amp;lt;/asp:TextBox&amp;gt;&lt;br /&gt;&amp;lt;br /&amp;gt;&lt;br /&gt;   &amp;lt;asp:Button ID="btnSelect" runat="server" Text="SingleSelect"&lt;br /&gt;       UseSubmitBehavior="False"  OnClientClick="CallSingle(); return false;"/&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;div id="result1"&amp;gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;11. Add Javascript code&lt;/span&gt;&lt;br /&gt;Add some javascript code to call the WCF service and process the results. Place this inside the head-tag, below the title tag:&lt;br /&gt;&lt;pre&gt;&amp;lt;script type ="text/javascript"&amp;gt;&lt;br /&gt;function CallSingle()&lt;br /&gt;{&lt;br /&gt;  dotnetbyexample.JSONDemoService.IJSONService.GetSingleObject(&lt;br /&gt;        document.getElementById("tbId").value,&lt;br /&gt;        document.getElementById("tbName").value,&lt;br /&gt;        CallBackSingle );&lt;br /&gt;}&lt;br /&gt;function CallBackSingle( WebServiceResult )&lt;br /&gt;{&lt;br /&gt;resultDiv = document.getElementById("result1");&lt;br /&gt;resultDiv.innerHTML = "You entered: id = " +&lt;br /&gt;     WebServiceResult.Id + " name = " +&lt;br /&gt;     WebServiceResult.Name;&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;Notice again that calling a WCF method from javascript works the same as when using asmx services: one extra parameter at the end of the list is required, which is the callback. This is a function that is called upon receiving the result from the server - the server method result is put into the single parameter of the callback.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;12. Run the test page&lt;/span&gt;&lt;br /&gt;Run Test1Form.aspx. You should be able to input and numerical id and a alphanumeric name, which are sent to the server, and returned back to you as and SampleObject.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;13. Deploying WCF services in IIS&lt;/span&gt;&lt;br /&gt;This all works fine when running it in Cassini, but when you want to host it in IIS, you will need to take care two things.&lt;br /&gt;&lt;br /&gt;First, you will need to ensure that IIS and WCF are correctly installed and registered. If IIS does not seem to want to cough up your SVC files (you can check that by trying http://&amp;lt;your host here&amp;gt;/&amp;lt;your sitename here&amp;gt;/AjaxService.svc), try running the command &lt;b&gt;ServiceModelReg.exe /i /x&lt;/b&gt; from %WINDIR%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation. Restart IIS after running this command.&lt;br /&gt;&lt;br /&gt;Second, if you created a default ASP.NET 2.0 website, you may run into this error message:&lt;pre&gt;IIS specified authentication schemes 'IntegratedWindowsAuthentication, Anonymous',&lt;br /&gt;but the binding only supports specification of exactly one authentication scheme.&lt;br /&gt;Valid authentication schemes are Digest, Negotiate, NTLM, Basic, or Anonymous.&lt;br /&gt;Change the IIS settings so that only a single authentication scheme is used.&lt;/pre&gt;To fix this, right-click the website in your IIS manager and choose "properties". Then click the "Directory" tab, click the "Edit" button in the "Anonymous access and authentication control" area. You will see that both Anonymous access and Integrated Windows Authentication are selected. Unselect one of them, then restart IIS. After that, the application should work smoothly.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Concluding remarks&lt;/span&gt;&lt;br /&gt;Calling WCF services from javascript is even simpler than calling asmx services - you don't even have to mark a service as [ScriptService] anymore, you just put an .svc file into your web site with four lines of code, make a reference to an existing service library and you're done.&lt;br /&gt;&lt;br /&gt;The sample described here does not use the IJSONService.GetMultipleObjects method, but you can download a the complete source code which includes a second test page that does. Notice that although GetMultipleObjects returns a ICollection&lt;sampledataobject&gt;, in javascript this is translated into a simple array. Thus, you can also use data and operation contract that use generic types, as long as the can simply be translated into an array.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/sampledataobject&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/864116869953733620-2624548266030658910?l=narulaamitsk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://narulaamitsk.blogspot.com/feeds/2624548266030658910/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=864116869953733620&amp;postID=2624548266030658910' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/2624548266030658910'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/2624548266030658910'/><link rel='alternate' type='text/html' href='http://narulaamitsk.blogspot.com/2009/07/calling-wcf-service-from-javascript.html' title='Calling a WCF service from Javascript'/><author><name>Amit Narula</name><uri>http://www.blogger.com/profile/03373886236261160868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_KIFo2nRsLTc/SfIq-GgjUkI/AAAAAAAACCo/bBDItRMEB6s/S220/DSCF1775.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-864116869953733620.post-3045109328210178395</id><published>2009-07-05T00:12:00.000-07:00</published><updated>2009-07-05T00:18:49.527-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Master Pages'/><title type='text'>The right way of accessing Master page properties from a child page</title><content type='html'>Master pages are a superbe idea. But sometimes you need to access Master Page properties from the child page.  Suppose, for instance, you have a button on the Master Page with a text that you want to be able to set:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;%@ Master Language="C#" AutoEventWireup="true" CodeBehind="MyDemoMaster.master.cs"&lt;br /&gt;Inherits="MasterPageDemo.MyDemoMaster" %&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"&lt;br /&gt; "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;html xmlns="http://www.w3.org/1999/xhtml"&amp;gt;&lt;br /&gt;&amp;lt;head runat="server"&amp;gt;&lt;br /&gt;   &amp;lt;title&amp;gt;Untitled Page&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;   &amp;lt;form id="form1" runat="server"&amp;gt;&lt;br /&gt;   &amp;lt;div&amp;gt;&lt;br /&gt;       &amp;lt;asp:button id="btnWithText" runat="server" text="Button"&amp;gt;&lt;br /&gt;        &amp;lt;asp:contentplaceholder id="ContentPlaceHolder1" runat="server"&amp;gt;&lt;br /&gt;       &amp;lt;/asp:ContentPlaceHolder&amp;gt;&lt;br /&gt;   &amp;lt;/div&amp;gt;&lt;br /&gt;   &amp;lt;/form&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In the Master Page, you can create a property like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;public string ButtonText&lt;br /&gt;{&lt;br /&gt;  get { return this.btnWithText.Text;  }&lt;br /&gt;  set { this.btnWithText.Text  = value; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Unfortunately, if you try to find the property "Master.ButtonText" in the childpage, it won't be available since the "Master" property is of type System.Web.UI.Page, and that does not contain properties of your derived class "MyDemoMaster"&lt;br /&gt;&lt;br /&gt;This, of course, can be solved by changing the Page_Load of the child page like this:&lt;br /&gt;&lt;pre&gt;protected void Page_Load(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt; MyDemoMaster m = Master as MyDemoMaster;&lt;br /&gt; m.ButtonText = "My button text";&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Congratulations. Your button shows the right text. And you have succeeded into locking your child page to a single master. Your web page will not run when you try to use another master page. Go back to programming class 101 and you don't get any cookies today ;-)&lt;br /&gt;&lt;br /&gt;The right solution is: create an interface like this:&lt;br /&gt;&lt;pre&gt;namespace MasterPageDemo&lt;br /&gt;{&lt;br /&gt;   public interface IButtonText&lt;br /&gt;   {&lt;br /&gt;       string ButtonText { get;set;}&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Open the code behind file of your Master Page and let it implement the interface:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;public partial class MyDemoMaster : System.Web.UI.MasterPage&lt;span style="font-weight: bold;"&gt;, IButtonText&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;   protected void Page_Load(object sender, EventArgs e)&lt;br /&gt;   {&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public string ButtonText&lt;br /&gt;   {&lt;br /&gt;       get { return this.btnWithText.Text;  }&lt;br /&gt;       set { this.btnWithText.Text  = value; }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And then you make the Page_Load of the child page like this&lt;br /&gt;&lt;pre&gt;protected void Page_Load(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt; IButtonText m = Master as IButtonText ;&lt;br /&gt; if( m != null ) m.ButtonText = "My button text";&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now the Master Page and Child Page are no longer coupled by name. Any Master Page implementing the IButtonText interface may be used as a Master Page for your child. Checking if it can be casted by testing m != null is a nice encore.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/864116869953733620-3045109328210178395?l=narulaamitsk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://narulaamitsk.blogspot.com/feeds/3045109328210178395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=864116869953733620&amp;postID=3045109328210178395' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/3045109328210178395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/3045109328210178395'/><link rel='alternate' type='text/html' href='http://narulaamitsk.blogspot.com/2009/07/right-way-of-accessing-master-page.html' title='The right way of accessing Master page properties from a child page'/><author><name>Amit Narula</name><uri>http://www.blogger.com/profile/03373886236261160868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_KIFo2nRsLTc/SfIq-GgjUkI/AAAAAAAACCo/bBDItRMEB6s/S220/DSCF1775.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-864116869953733620.post-8673817559168496799</id><published>2009-06-23T00:34:00.000-07:00</published><updated>2009-07-05T00:45:44.368-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dataset'/><category scheme='http://www.blogger.com/atom/ns#' term='DataGrid'/><category scheme='http://www.blogger.com/atom/ns#' term='DataTables'/><title type='text'></title><content type='html'>    &lt;h2&gt;&lt;a name="_Toc56951000"&gt;&lt;/a&gt;&lt;a name="_Toc55609966"&gt;1 Introduction&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;The purpose of this document is to provide a practical guide to using Microsoft’s .NET &lt;code&gt;DataTables&lt;/code&gt;, &lt;code&gt;DataSets &lt;/code&gt;and &lt;code&gt;DataGrid&lt;/code&gt;. Most articles illustrate how to use the &lt;code&gt;DataGrid &lt;/code&gt;when directly bound to tables within a database and even though this is an excellent way to use the DataGrid, it is also able to display and manage programmatically created and linked tables and datasets composed of these tables without being bound to a database. Microsoft’s implementation has provided a rich syntax for populating and accessing rows and their cells within tables, for managing collections of tables, columns, rows and table styles and for managing inserts, updates, deletes and events. Microsoft’s Visual Studio .NET development environment provides detailed explanations and code examples for the classes, which is excellent for obtaining a quick reference to a method or property, but not for understanding how they all fit together and are used in applications. &lt;/p&gt;  &lt;p&gt;This article will present different ways to create and manage bound and unbound tables and datasets and to bind them to &lt;code&gt;DataGrids &lt;/code&gt;for use by WebForms and WinForms. The different behaviors of the DataGrid depending upon whether it is in a WebForm or a WinForm will be presented. In addition, copying &lt;code&gt;DataGrid &lt;/code&gt;content to the clipboard, importing and exporting in XML and printing will be presented. Techniques for linking &lt;code&gt;DataGrid &lt;/code&gt;content to features within graphics objects to provide an interactive UI will be discussed in the last section.&lt;/p&gt;  &lt;p&gt;The intent of this article is not to be a complete reference for all methods and members of the classes used for building Tables, Datasets and DataGrids, but to illustrate systematically how to build and manage them using their essential methods and properties. The article will also show equivalent ways for working with these entities to illustrate programming flexibility options. Once they are built the tables can be added to a database and/or the content easily extracted for updating existing database tables. &lt;/p&gt;  &lt;p&gt;The structure and features of a table created using the DataTable class is at the heart of using the DataGrid; therefore, it will be presented first. Next the DataSet that manages collections of independent and linked tables will be presented followed by the DataGrid that displays and provides an interactive UI for its Tables and Datasets. All example code will be written in C# and the periodic table with its elements and isotopes will be used as a model and source of data. &lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc56951001"&gt;&lt;/a&gt;&lt;a name="_Toc55609967"&gt;2 Overview&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Figure 1 is a summary view of the essential relationships between the &lt;code&gt;DataGrid&lt;/code&gt;, &lt;code&gt;DataGridTableStyles&lt;/code&gt;, &lt;code&gt;DataSets &lt;/code&gt;and &lt;code&gt;DataTables &lt;/code&gt;and their various methods and properties. This article will delve into the details of each of these components describing how to create them, to fill them with data and how they work together and thereby provide a clearer understanding of this relationship diagram. &lt;/p&gt; &lt;img src="http://www.codeproject.com/KB/grid/PracticalGuideDataGrids1/image002.gif" width="575" height="420"&gt;  &lt;p&gt;Figure 1 DataGrid, DataSet and DataTable relationship diagram&lt;/p&gt;&lt;h2&gt;&lt;a name="_Toc55609968"&gt;3 Tables&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;The architecture and capability of Tables should be understood since it carries over to understanding how a &lt;code&gt;DataSet &lt;/code&gt;and &lt;code&gt;DataGrid &lt;/code&gt;function. In the process of binding a DataGrid to a database the underlying code creates and associates collections of tables that are filled with data from the database. Also, a DataSet created from a database may contain tables with more information than needs to be displayed, columns may need to be added that are based upon complex formulas using information in other columns and data from multiple databases may need to be combined into a single tabular view. These operations are done by extracting information from these data sources and by filling a programmatically designed table that is unbound.&lt;/p&gt;  &lt;p&gt;Fundamentally a table contains &lt;code&gt;Columns &lt;/code&gt;and &lt;code&gt;Rows &lt;/code&gt;collections, which means standard methods for accessing and manipulating collections can be used. The &lt;code&gt;Columns &lt;/code&gt;collection contains, for each column, a name, a data type specification and maybe an assigned default value. Each table row in the Rows collection contains one cell for each column. The table class has an extensive set of methods for editing and managing versions of column and row data and for event notifications when changes occur. Figure 2 illustrates the overall architecture of a table.&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.codeproject.com/KB/grid/PracticalGuideDataGrids2/image003.gif" width="588" height="568"&gt;&lt;/p&gt;  &lt;p&gt;Figure 2 DataTable Decomposed&lt;/p&gt;  &lt;h2&gt;&lt;a name="_Toc56951003"&gt;&lt;/a&gt;&lt;a name="_Toc55609969"&gt;3.1 Table creation&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;A table memory object that will be able to contain/manage columns, rows and events can be easily created from the DataTable class as follows:&lt;/p&gt;  &lt;div class="SmallText" id="premain0" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="0" src="http://www.codeproject.com/images/minus.gif" id="preimg0" width="9" height="9"&gt;&lt;span preid="0" style="margin-bottom: 0pt;" id="precollapse0"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre0" lang="cs"&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Create a table object by using the DataTable class:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;DataTable dt = &lt;span class="code-keyword"&gt;new&lt;/span&gt; DataTable();&lt;br /&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Name the table by assigning a data string containing &lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; the name to the table’s&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; TableName property:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;dt.TableName = “Elements”;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; or use the DataTable(string TableName) constructor&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;DataTable dt = &lt;span class="code-keyword"&gt;new&lt;/span&gt; DataTable(“Elements”);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;  &lt;h2&gt;&lt;a name="_Toc56951004"&gt;&lt;/a&gt;&lt;a name="_Toc55609970"&gt;3.2 Columns – Creating and Adding to Tables&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;A table contains a collection of column definitions that will be used to define how each cell within a row can be referenced and the type of data content. The following scenario shows how to define a column and add it to a table’s column collection.&lt;/p&gt;  &lt;p&gt;a. Define a Table as described in the Tables section.&lt;/p&gt;  &lt;p&gt;b. Create a column object to be added to the table by using the column class:&lt;/p&gt;  &lt;div class="SmallText" id="premain1" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="1" src="http://www.codeproject.com/images/minus.gif" id="preimg1" width="9" height="9"&gt;&lt;span preid="1" style="margin-bottom: 0pt;" id="precollapse1"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre1" lang="cs"&gt;DataColumn dc = &lt;span class="code-keyword"&gt;new&lt;/span&gt; DataColumn();&lt;br /&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Set the properties for the column:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; string name for the column that is used as an index &lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; for columns collection&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; and a cell within a row&lt;/span&gt;&lt;br /&gt;dc.ColumnName = “AtomicNbr”;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; string name that is used for a column label or header &lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; for display purposes&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; if not set, then the default value is dc.ColumnName&lt;/span&gt;&lt;br /&gt;dc.Caption = “Atomic Number”;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; one of the standard system data types using the&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; GetType() method.&lt;/span&gt;&lt;br /&gt;dc.DataType = System.Type.GetType(“System.&lt;span class="code-SDKkeyword"&gt;Int32&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; or one could use the typeof operator&lt;/span&gt;&lt;br /&gt;dc.DataType = &lt;span class="code-keyword"&gt;typeof&lt;/span&gt;(System.&lt;span class="code-SDKkeyword"&gt;Int32&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; a default value that is assigned each time &lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; a new row is created&lt;/span&gt;&lt;br /&gt;dc.DefaultValue = &lt;span class="code-digit"&gt;0&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; or use one of the other constructor’s such as&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; DataColumn(string ColumnName, System.Type DataType)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;DataColumn dc = &lt;span class="code-keyword"&gt;new&lt;/span&gt; DataColumn(“AtomicNbr”,&lt;br /&gt; System.Type.GetType(“System.Int32”));&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;c. Add the new column to the table &lt;code lang="cs"&gt;Columns&lt;/code&gt; collection. The order in which the columns are added determines their zero-based index.&lt;/p&gt;  &lt;div class="SmallText" id="premain2" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="2" src="http://www.codeproject.com/images/minus.gif" id="preimg2" width="9" height="9"&gt;&lt;span preid="2" style="margin-bottom: 0pt;" id="precollapse2"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre2" lang="cs"&gt;dt.Columns.Add(dc);&lt;/pre&gt;  &lt;p&gt;d. Repeat b and c for each column to be added to the table &lt;code lang="cs"&gt;Columns&lt;/code&gt; collection.&lt;/p&gt;  &lt;div class="SmallText" id="premain3" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="3" src="http://www.codeproject.com/images/minus.gif" id="preimg3" width="9" height="9"&gt;&lt;span preid="3" style="margin-bottom: 0pt;" id="precollapse3"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre3" lang="cs"&gt;dc = &lt;span class="code-keyword"&gt;new&lt;/span&gt; DataColumn(“Element”, System.Type.GetType(“System.String”));&lt;br /&gt;dc.DefaultValue = &lt;span class="code-keyword"&gt;string&lt;/span&gt;.Empty;&lt;br /&gt;dc.Caption = “Element”;&lt;br /&gt;dt.Columns.Add(dc);&lt;br /&gt;&lt;br /&gt;dc = &lt;span class="code-keyword"&gt;new&lt;/span&gt; DataColumn(“Symbol”, System.Type.GetType(“System.String”) );&lt;br /&gt;dc.DefaultValue = &lt;span class="code-keyword"&gt;string&lt;/span&gt;.Empty;&lt;br /&gt;dc.Caption = “Symbol”;&lt;br /&gt;dt.Columns.Add(dc);&lt;br /&gt;&lt;br /&gt;dc = &lt;span class="code-keyword"&gt;new&lt;/span&gt; DataColumn(“AtomicMass”, System.Type.GetType(“System.Decimal”) );&lt;br /&gt;dc.DefaultValue = &lt;span class="code-digit"&gt;0&lt;/span&gt;.&lt;span class="code-digit"&gt;0&lt;/span&gt;;&lt;br /&gt;dc.Caption = “Atomic Mass”;&lt;br /&gt;dt.Columns.Add(dc);&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;Examples of data types supported in the .NET environment.&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="199"&gt;&lt;strong&gt;Data Type&lt;/strong&gt;&lt;/td&gt;  &lt;td width="367"&gt;&lt;strong&gt;.NET System Types&lt;/strong&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td valign="top" width="199"&gt;&lt;code lang="cs"&gt;&lt;span class="code-SDKkeyword"&gt;Boolean&lt;/span&gt;&lt;/code&gt; &lt;/td&gt;  &lt;td width="367"&gt;&lt;code lang="cs"&gt;System.&lt;span class="code-SDKkeyword"&gt;Boolean&lt;/span&gt;&lt;/code&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="199"&gt;&lt;code lang="cs"&gt;&lt;span class="code-SDKkeyword"&gt;Byte&lt;/span&gt;&lt;/code&gt;&lt;/td&gt;  &lt;td width="367"&gt;&lt;code lang="cs"&gt;System.&lt;span class="code-SDKkeyword"&gt;Byte&lt;/span&gt;&lt;/code&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="199"&gt;&lt;code lang="cs"&gt;&lt;span class="code-SDKkeyword"&gt;Byte&lt;/span&gt;[] (Array)&lt;/code&gt;&lt;/td&gt;  &lt;td width="367"&gt;&lt;code lang="cs"&gt;System.&lt;span class="code-SDKkeyword"&gt;Byte&lt;/span&gt;[]&lt;/code&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="199"&gt;&lt;code lang="cs"&gt;Char (Chararacter)&lt;/code&gt;&lt;/td&gt;  &lt;td width="367"&gt;&lt;code lang="cs"&gt;System.Char&lt;/code&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="199"&gt;&lt;code lang="cs"&gt;DateTime&lt;/code&gt;&lt;/td&gt;  &lt;td width="367"&gt;&lt;code lang="cs"&gt;System.DateTime&lt;/code&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="199"&gt;&lt;code lang="cs"&gt;Decimal&lt;/code&gt;&lt;/td&gt;  &lt;td width="367"&gt;&lt;code lang="cs"&gt;System.Decimal&lt;/code&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="199"&gt;&lt;code lang="cs"&gt;&lt;span class="code-SDKkeyword"&gt;Double&lt;/span&gt;&lt;/code&gt;&lt;/td&gt;  &lt;td width="367"&gt;&lt;code lang="cs"&gt;System.&lt;span class="code-SDKkeyword"&gt;Double&lt;/span&gt;&lt;/code&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="199"&gt;&lt;code lang="cs"&gt;Integer&lt;/code&gt;&lt;/td&gt;  &lt;td width="367"&gt;&lt;code lang="cs"&gt;System.&lt;span class="code-SDKkeyword"&gt;Int16&lt;/span&gt;, System.&lt;span class="code-SDKkeyword"&gt;Int32&lt;/span&gt;, System.&lt;span class="code-SDKkeyword"&gt;Int64&lt;/span&gt;&lt;/code&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="199"&gt;&lt;code lang="cs"&gt;&lt;span class="code-SDKkeyword"&gt;Single&lt;/span&gt;&lt;/code&gt;&lt;/td&gt;  &lt;td width="367"&gt;&lt;code lang="cs"&gt;System.&lt;span class="code-SDKkeyword"&gt;Single&lt;/span&gt;&lt;/code&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="199"&gt;&lt;code lang="cs"&gt;&lt;span class="code-SDKkeyword"&gt;String&lt;/span&gt;&lt;/code&gt;&lt;/td&gt;  &lt;td width="367"&gt;&lt;code lang="cs"&gt;System.&lt;span class="code-SDKkeyword"&gt;String&lt;/span&gt;&lt;/code&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="199"&gt;&lt;code lang="cs"&gt;Unsigned Integer&lt;/code&gt;&lt;/td&gt;  &lt;td width="367"&gt;&lt;code lang="cs"&gt;System.&lt;span class="code-SDKkeyword"&gt;UInt16&lt;/span&gt;, System.&lt;span class="code-SDKkeyword"&gt;UInt32&lt;/span&gt;, System.&lt;span class="code-SDKkeyword"&gt;UInt64&lt;/span&gt;&lt;/code&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="199"&gt;&lt;code lang="cs"&gt;TimeSpan&lt;/code&gt;&lt;/td&gt;  &lt;td width="367"&gt;&lt;code lang="cs"&gt;System.TimeSpan&lt;/code&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;At this point a table called “Elements” has been created with four columns “AtomicNbr”, “Element”, “Symbol” and “AtomicMass” with their respective data types and default values. The following three &lt;code lang="cs"&gt;DisplayColumnInfo()&lt;/code&gt;&lt;em&gt; &lt;/em&gt;method code examples show this by using different techniques for accessing members and displaying data from their collections. In the first example, a for-loop is used to illustrate accessing table column collections through an integer index while in the second example a &lt;code lang="cs"&gt;&lt;span class="code-keyword"&gt;foreach&lt;/span&gt;&lt;/code&gt; loop illustrates accessing the same collections using a column class type. The third example uses strings containing the column names as an index. These accessing data examples illustrate the natural syntax approaches for working with collections.&lt;/p&gt;  &lt;p&gt;1. &lt;code lang="cs"&gt;&lt;span class="code-keyword"&gt;for&lt;/span&gt;&lt;/code&gt;-loop&lt;/p&gt;  &lt;div class="SmallText" id="premain4" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="4" src="http://www.codeproject.com/images/minus.gif" id="preimg4" width="9" height="9"&gt;&lt;span preid="4" style="margin-bottom: 0pt;" id="precollapse4"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre4" lang="cs"&gt;&lt;span class="code-keyword"&gt;private&lt;/span&gt; &lt;span class="code-keyword"&gt;void&lt;/span&gt; DisplayColumnInfo(DataTable dt)&lt;br /&gt;{lder ColInfo = &lt;span class="code-keyword"&gt;new&lt;/span&gt; StringBuilder();&lt;br /&gt;ColInfo.AppendFormat(“Column\tName\tDataType\n”);&lt;br /&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; note that the total number of columns in the &lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; collection is contained in the ‘Count’ property&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;for&lt;/span&gt;(&lt;span class="code-keyword"&gt;int&lt;/span&gt; j=0; j&lt;dt.Columns.Count; j++)&lt;br /&gt;{&lt;br /&gt; ColInfo.AppendFormat(“ [{&lt;span class="code-digit"&gt;0&lt;/span&gt;}]\t{&lt;span class="code-digit"&gt;1&lt;/span&gt;}\t{&lt;span class="code-digit"&gt;2&lt;/span&gt;}\ t{&lt;span class="code-digit"&gt;3&lt;/span&gt;}\n”, j,&lt;br /&gt;   dt.Columns[j].ColumnName,&lt;br /&gt;   dt.Columns[j].Caption, dt.Columns[j].DataType.ToString());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;MessageBox.Show(ColInfo.ToString() , “Column Name”,&lt;br /&gt;  MessageBoxButtons.OK,&lt;br /&gt;MessageBoxIcon.Information);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;2. &lt;code lang="cs"&gt;&lt;span class="code-keyword"&gt;foreach&lt;/span&gt;&lt;/code&gt; loop&lt;/p&gt;  &lt;div class="SmallText" id="premain5" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="5" src="http://www.codeproject.com/images/minus.gif" id="preimg5" width="9" height="9"&gt;&lt;span preid="5" style="margin-bottom: 0pt;" id="precollapse5"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre5" lang="cs"&gt;&lt;span class="code-keyword"&gt;private&lt;/span&gt; &lt;span class="code-keyword"&gt;void&lt;/span&gt; DisplayColumnInfo(DataTable dt)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; StringBuilder ColInfo = &lt;span class="code-keyword"&gt;new&lt;/span&gt; StringBuilder();&lt;br /&gt; ColInfo.AppendFormat(“Column\tName\tDataType\n”);&lt;br /&gt; &lt;span class="code-keyword"&gt;int&lt;/span&gt; j = -1;&lt;br /&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;foreach&lt;/span&gt; (DataColumn dc &lt;span class="code-keyword"&gt;in&lt;/span&gt; dt.Columns)&lt;br /&gt; {&lt;br /&gt;  ColInfo.AppendFormat(“ [{&lt;span class="code-digit"&gt;0&lt;/span&gt;}]\t{&lt;span class="code-digit"&gt;1&lt;/span&gt;}\t{&lt;span class="code-digit"&gt;2&lt;/span&gt;}\t{&lt;span class="code-digit"&gt;3&lt;/span&gt;}\n”, ++j, dc.ColumnName,&lt;br /&gt;  dc.Caption, dc.DataType.ToString() );&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; MessageBox.Show(ColInfo.ToString(),&lt;br /&gt;   “Column Name”, MessageBoxButtons.OK,&lt;br /&gt; MessageBoxIcon.Information);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;3. Using known column names as indexes – not column captions!&lt;/p&gt;  &lt;div class="SmallText" id="premain6" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="6" src="http://www.codeproject.com/images/minus.gif" id="preimg6" width="9" height="9"&gt;&lt;span preid="6" style="margin-bottom: 0pt;" id="precollapse6"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre6" lang="cs"&gt;&lt;span class="code-keyword"&gt;private&lt;/span&gt; &lt;span class="code-keyword"&gt;void&lt;/span&gt; DisplayColumnDataTypeInfo(DataTa} &lt;/pre&gt;  &lt;p&gt;3. Using known column names as indexes – not column captions!&lt;/p&gt;  &lt;div class="SmallText" id="premain7" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="7" src="http://www.codeproject.com/images/minus.gif" id="preimg7" width="9" height="9"&gt;&lt;span preid="7" style="margin-bottom: 0pt;" id="precollapse7"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre7" lang="cs"&gt;&lt;span class="code-keyword"&gt;private&lt;/span&gt; &lt;span class="code-keyword"&gt;void&lt;/span&gt; DisplayColumnDataTypeInfo(DataTable dt)&lt;br /&gt;{&lt;br /&gt; StringBuilder ColInfo = &lt;span class="code-keyword"&gt;new&lt;/span&gt; StringBuilder();&lt;br /&gt; ColInfo.AppendFormat(“Column\tName\tDataType\n”);&lt;br /&gt;&lt;br /&gt; ColInfo.AppendFormat(“ [{&lt;span class="code-digit"&gt;0&lt;/span&gt;}]\t{&lt;span class="code-digit"&gt;1&lt;/span&gt;}\t{&lt;span class="code-digit"&gt;2&lt;/span&gt;}\n”,&lt;span class="code-digit"&gt;1&lt;/span&gt;, “AtomicNbr”,&lt;br /&gt; dt.Columns[“AtomicNbr”].DataType.ToString());&lt;br /&gt;&lt;br /&gt; ColInfo.AppendFormat(“ [{&lt;span class="code-digit"&gt;0&lt;/span&gt;}]\t{&lt;span class="code-digit"&gt;1&lt;/span&gt;}\t{&lt;span class="code-digit"&gt;2&lt;/span&gt;}\n”,&lt;span class="code-digit"&gt;1&lt;/span&gt;, “Element”,&lt;br /&gt; dt.Columns[“Element”].DataType.ToString());&lt;br /&gt;&lt;br /&gt; ColInfo.AppendFormat(“ [{&lt;span class="code-digit"&gt;0&lt;/span&gt;}]\t{&lt;span class="code-digit"&gt;1&lt;/span&gt;}\t{&lt;span class="code-digit"&gt;2&lt;/span&gt;}\n”,&lt;span class="code-digit"&gt;1&lt;/span&gt;, “Symbol”,&lt;br /&gt; dt.Columns[“Symbol”].DataType.ToString());&lt;br /&gt;&lt;br /&gt; ColInfo.AppendFormat(“ [{&lt;span class="code-digit"&gt;0&lt;/span&gt;}]\t{&lt;span class="code-digit"&gt;1&lt;/span&gt;}\t{&lt;span class="code-digit"&gt;2&lt;/span&gt;}\n”,&lt;span class="code-digit"&gt;1&lt;/span&gt;, “AtomicMass”,&lt;br /&gt; dt.Columns[“AtomicMass”].DataType.ToString());&lt;br /&gt;&lt;br /&gt; MessageBox.Show(ColInfo.ToString() , “Column Name”,&lt;br /&gt; MessageBoxButtons.OK,&lt;br /&gt; MessageBoxIcon.Information);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;  &lt;h2&gt;&lt;a name="_Toc56951005"&gt;&lt;/a&gt;&lt;a name="_Toc55609971"&gt;3.3 Deleting/Removing Columns&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Once a table has been defined columns can be deleted or removed as follows:&lt;/p&gt;  &lt;div class="SmallText" id="premain8" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="8" src="http://www.codeproject.com/images/minus.gif" id="preimg8" width="9" height="9"&gt;&lt;span preid="8" style="margin-bottom: 0pt;" id="precollapse8"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre8" lang="cs"&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; For example to delete a column “AtomicMass”&lt;/span&gt;&lt;br /&gt;dt.Columns.Remove(“AtomicMass”);&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; or using a zero-based index – “AtomicMass” is the&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; 4th column with index 3&lt;/span&gt;&lt;br /&gt;dt.Columns.RemoveAt(&lt;span class="code-digit"&gt;3&lt;/span&gt;);&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; To make sure that a column can be removed,&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; for example, first determine&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; whether the column exists, belongs to the table,&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; or is involved in a constraint&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; or relation.&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;if&lt;/span&gt; (dt.Columns.Contains(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;AtomicMass"&lt;/span&gt;))&lt;br /&gt; &lt;span class="code-keyword"&gt;if&lt;/span&gt; (dt.Columns.CanRemove(dt.Columns[&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;AtomicMass"&lt;/span&gt;])&lt;br /&gt; {&lt;br /&gt;  dt.Columns.Remove(“AtomicMass”);&lt;br /&gt; }&lt;/pre&gt;  &lt;h2&gt;&lt;a name="_Toc56951006"&gt;&lt;/a&gt;&lt;a name="_Toc55609972"&gt;3.4 Modifying Column Properties&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Modifying a column property is simply accessing the property and setting its new value. For example:&lt;/p&gt;  &lt;div class="SmallText" id="premain9" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="9" src="http://www.codeproject.com/images/minus.gif" id="preimg9" width="9" height="9"&gt;&lt;span preid="9" style="margin-bottom: 0pt;" id="precollapse9"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre9" lang="cs"&gt;dt.Columns[“AtomicNbr”].ColumnName = “AtomicNumber”;&lt;br /&gt;dt.Columns[“AtomicMass”].DataType = &lt;span class="code-keyword"&gt;typeof&lt;/span&gt;(System.&lt;span class="code-keyword"&gt;float&lt;/span&gt;);&lt;/pre&gt;  &lt;h2&gt;&lt;a name="_Toc56951007"&gt;&lt;/a&gt;&lt;a name="_Toc55609973"&gt;3.5 Clearing Column Collection&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;The entire table column collection can be cleared by simply using the &lt;code lang="cs"&gt;Clear() &lt;/code&gt;method.&lt;/p&gt;  &lt;div class="SmallText" id="premain10" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="10" src="http://www.codeproject.com/images/minus.gif" id="preimg10" width="9" height="9"&gt;&lt;span preid="10" style="margin-bottom: 0pt;" id="precollapse10"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre10" lang="cs"&gt;dt.Columns.Clear();&lt;/pre&gt;  &lt;h2&gt;&lt;a name="_Toc56951008"&gt;&lt;/a&gt;&lt;a name="_Toc55609974"&gt;3.6 Cloning a Table&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;Once a table has been defined it can be used to create an identical table with the same column collection or it can be used as a basis for a new table where columns will be deleted, added or modified. The original table’s &lt;code lang="cs"&gt;Clone() &lt;/code&gt;method is used to create the new table with the same structure including schemas and constraints; however, it does not copy the content contained in the rows.&lt;/p&gt;  &lt;div class="SmallText" id="premain11" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="11" src="http://www.codeproject.com/images/minus.gif" id="preimg11" width="9" height="9"&gt;&lt;span preid="11" style="margin-bottom: 0pt;" id="precollapse11"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre11" lang="cs"&gt;DataTable dt1 = dt.Clone();&lt;/pre&gt;  &lt;p&gt;Now dt1 can be changed, for example:&lt;/p&gt;  &lt;div class="SmallText" id="premain12" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="12" src="http://www.codeproject.com/images/minus.gif" id="preimg12" width="9" height="9"&gt;&lt;span preid="12" style="margin-bottom: 0pt;" id="precollapse12"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre12" lang="cs"&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; delete a column&lt;/span&gt;&lt;br /&gt;dt1.Columns.Remove(“AtomicMass”);&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; add a new column to the table&lt;/span&gt;&lt;br /&gt;dc = &lt;span class="code-keyword"&gt;new&lt;/span&gt; DataColumn(“IsotopeNbr”,&lt;br /&gt;System.Type.GetType(“System.Int32”));&lt;br /&gt;dc.DefaultValue = &lt;span class="code-digit"&gt;0&lt;/span&gt;;&lt;br /&gt;dt1.Columns.Add(dc);&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; modify the name and caption of an existing column&lt;/span&gt;&lt;br /&gt;dt1.Columns[“AtomicNbr”].ColumnName = “AtomicNumber”;&lt;br /&gt;dt1.Columns[“AtomicNbr”].Caption = “Atomic Number”;&lt;/pre&gt;  &lt;h2&gt;&lt;a name="_Toc56951009"&gt;&lt;/a&gt;&lt;a name="_Toc55609975"&gt;3.7 Rows – creating and adding to a table.&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;This section will show how to add rows and assign values to rows in the table rows collection using four equivalent methods for accessing individual cells within a row. The choice of method really depends upon the type of task such as the source of the data being used to fill the rows or simply extracting data from the rows.&lt;/p&gt;  &lt;p&gt;1. Define a Table with Columns as described in the Tables and Columns section&lt;/p&gt;  &lt;p&gt;2. The following scenario is the fundamental procedure for creating a row, filling the cells in the row and then adding the row to the table. This section also illustrates equivalent ways to index a cell, which provides the developer with much flexibility.&lt;/p&gt;  &lt;div class="SmallText" id="premain13" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="13" src="http://www.codeproject.com/images/minus.gif" id="preimg13" width="9" height="9"&gt;&lt;span preid="13" style="margin-bottom: 0pt;" id="precollapse13"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre13" lang="cs"&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; First create a DataRow variable&lt;/span&gt;&lt;br /&gt;DataRow dr;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Next create a new row and assign it to the DataRow&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; object dr using DataTable’s&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; NewRow() method.&lt;/span&gt;&lt;br /&gt;dr = dt.NewRow();&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; dr now contains a cell for each column defined in the&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Columns collection &lt;/span&gt;&lt;/pre&gt;  &lt;p&gt;&lt;em&gt;Four equivalent methods used to assign values to individual cells within a row. &lt;/em&gt;&lt;/p&gt;  &lt;h3&gt;Method 1&lt;/h3&gt;  &lt;div class="SmallText" id="premain14" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="14" src="http://www.codeproject.com/images/minus.gif" id="preimg14" width="9" height="9"&gt;&lt;span preid="14" style="margin-bottom: 0pt;" id="precollapse14"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre14" lang="cs"&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; fill each cell using a zero-based cell integer column indexes&lt;/span&gt;&lt;br /&gt;dr[&lt;span class="code-digit"&gt;0&lt;/span&gt;] = &lt;span class="code-digit"&gt;1&lt;/span&gt;;&lt;br /&gt;dr[&lt;span class="code-digit"&gt;1&lt;/span&gt;] = “Hydrogen”;&lt;br /&gt;dr[&lt;span class="code-digit"&gt;2&lt;/span&gt;] = “H”;&lt;br /&gt;dr[&lt;span class="code-digit"&gt;3&lt;/span&gt;] = &lt;span class="code-digit"&gt;1&lt;/span&gt;.&lt;span class="code-digit"&gt;0078&lt;/span&gt;;&lt;/pre&gt;  &lt;h3&gt;Method 2&lt;/h3&gt;  &lt;div class="SmallText" id="premain15" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="15" src="http://www.codeproject.com/images/minus.gif" id="preimg15" width="9" height="9"&gt;&lt;span preid="15" style="margin-bottom: 0pt;" id="precollapse15"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre15" lang="cs"&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; fill each cell using the column name as the string column index&lt;/span&gt;&lt;br /&gt;dr[“AtomicNbr”] = &lt;span class="code-digit"&gt;1&lt;/span&gt;;&lt;br /&gt;dr[“Element”] = “Hydrogen”;&lt;br /&gt;dr[“Symbol”] = “H”;&lt;br /&gt;dr[“AtomicMass”] = &lt;span class="code-digit"&gt;1&lt;/span&gt;.&lt;span class="code-digit"&gt;0078&lt;/span&gt;;&lt;/pre&gt;  &lt;h3&gt;Method 3&lt;/h3&gt;  &lt;div class="SmallText" id="premain16" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="16" src="http://www.codeproject.com/images/minus.gif" id="preimg16" width="9" height="9"&gt;&lt;span preid="16" style="margin-bottom: 0pt;" id="precollapse16"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre16" lang="cs"&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; fill each cell using DataColumn dc -- this is more applicable&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; when using a DataColumn foreach loop&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; e.g. foreach (DataColumn dc in dt.Rows) …&lt;/span&gt;&lt;br /&gt;DataColumn dc;&lt;br /&gt;dc = dt.Columns[“AtomicNbr”];&lt;br /&gt;dr[dc] = &lt;span class="code-digit"&gt;1&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;dc = dt.Columns[“Element”];&lt;br /&gt;dr[dc] = “Hydrogen”;&lt;br /&gt;&lt;br /&gt;dc = dt.Columns[“Symbol”];&lt;br /&gt;dr[dc] = “H”;&lt;br /&gt;&lt;br /&gt;dc = dt.Columns[“AtomicMass”];&lt;br /&gt;dr[dc] = &lt;span class="code-digit"&gt;1&lt;/span&gt;.&lt;span class="code-digit"&gt;0078&lt;/span&gt;;&lt;/pre&gt;  &lt;h3&gt;Method 4&lt;/h3&gt;  &lt;div class="SmallText" id="premain17" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="17" src="http://www.codeproject.com/images/minus.gif" id="preimg17" width="9" height="9"&gt;&lt;span preid="17" style="margin-bottom: 0pt;" id="precollapse17"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre17" lang="cs"&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; fill each cell using DataColumn dc and its ColumnName property&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; which is identical to Method 3 but is&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; included here for completeness&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Again, more applicable when using a foreach loop&lt;/span&gt;&lt;br /&gt;DataColumn dc;&lt;br /&gt;dc = dt.Columns[“AtomicNbr”];&lt;br /&gt;dr[dc.ColumnName] = &lt;span class="code-digit"&gt;1&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;dc = dt.Columns[“Element”];&lt;br /&gt;dr[dc.ColumnName] = “Hydrogen”;&lt;br /&gt;&lt;br /&gt;dc = dt.Columns[“Symbol”];&lt;br /&gt;dr[dc.ColumnName] = “H”;&lt;br /&gt;&lt;br /&gt;dc = dt.Columns[“AtomicMass”];&lt;br /&gt;dr[dc.ColumnName] = &lt;span class="code-digit"&gt;1&lt;/span&gt;.&lt;span class="code-digit"&gt;0078&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; add the row to the table’s row collection&lt;/span&gt;&lt;br /&gt;dt.Rows.Add(dr);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;  &lt;p&gt;3. This scenario can be easily extended to a more general procedure to add n rows to the table. For example suppose a two dimensional object array ‘ElementData’ with n rows and dt.Columns.Count columns contains data to be added to the table. It could be loaded as follows:&lt;/p&gt;  &lt;div class="SmallText" id="premain18" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="18" src="http://www.codeproject.com/images/minus.gif" id="preimg18" width="9" height="9"&gt;&lt;span preid="18" style="margin-bottom: 0pt;" id="precollapse18"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre18" lang="cs"&gt;DataRow dr;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;int&lt;/span&gt; j;&lt;br /&gt;&lt;span class="code-keyword"&gt;for&lt;/span&gt; (&lt;span class="code-keyword"&gt;int&lt;/span&gt; i=0; i &lt; n; i++)&lt;br /&gt;{&lt;br /&gt; j = -1;&lt;br /&gt; dr = dt.NewRow();&lt;br /&gt; &lt;span class="code-keyword"&gt;foreach&lt;/span&gt; (DataColumn dc &lt;span class="code-keyword"&gt;in&lt;/span&gt; dt.Columns)&lt;br /&gt; {&lt;br /&gt;  j++;&lt;br /&gt;  &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; fill each cell, using the column dc as the index, from the&lt;/span&gt;&lt;br /&gt;  &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; previously defined two dimensional object array à ElementData&lt;/span&gt;&lt;br /&gt;  &lt;span class="code-keyword"&gt;if&lt;/span&gt; (dc.DataType == &lt;span class="code-keyword"&gt;typeof&lt;/span&gt;(System.&lt;span class="code-SDKkeyword"&gt;String&lt;/span&gt;))&lt;br /&gt;   dr[dc] = (System.&lt;span class="code-SDKkeyword"&gt;String&lt;/span&gt;)ElementData[i][j];&lt;br /&gt;  &lt;span class="code-keyword"&gt;else&lt;/span&gt;&lt;br /&gt;   &lt;span class="code-keyword"&gt;if&lt;/span&gt; (dc.DataType == &lt;span class="code-keyword"&gt;typeof&lt;/span&gt;(System.&lt;span class="code-SDKkeyword"&gt;Int32&lt;/span&gt;))&lt;br /&gt;    dr[dc] = (System.&lt;span class="code-SDKkeyword"&gt;Int32&lt;/span&gt;)ElementData[i][j];&lt;br /&gt;   &lt;span class="code-keyword"&gt;else&lt;/span&gt;&lt;br /&gt;    &lt;span class="code-keyword"&gt;if&lt;/span&gt; (dc.DataType == &lt;span class="code-keyword"&gt;typeof&lt;/span&gt;(System.Decimal))&lt;br /&gt;     dr[dc] = (System.Decimal)ElementData[i][j];&lt;br /&gt; }&lt;br /&gt; dt.Rows.Add(dr);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;  &lt;h2&gt;&lt;a name="_Toc56951010"&gt;&lt;/a&gt;&lt;a name="_Toc55609976"&gt;3.8 Modifying data within an existing table row&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;There are a number of ways to modify data in a table with the following illustrating the basic mechanism. Other techniques will be presented in the following sections.&lt;/p&gt;  &lt;div class="SmallText" id="premain19" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="19" src="http://www.codeproject.com/images/minus.gif" id="preimg19" width="9" height="9"&gt;&lt;span preid="19" style="margin-bottom: 0pt;" id="precollapse19"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre19" lang="cs"&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; First create a DataRow variable&lt;/span&gt;&lt;br /&gt;DataRow dr;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Next assign the row in the Rows collection&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; to be modified to dr, for example select row&lt;/span&gt;&lt;br /&gt;with index = &lt;span class="code-digit"&gt;0&lt;/span&gt;&lt;br /&gt;dr = dt.Rows[&lt;span class="code-digit"&gt;0&lt;/span&gt;];&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Select the&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; column within the row to be modified by specifying&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; a column index and assign&lt;/span&gt;&lt;br /&gt;the &lt;span class="code-keyword"&gt;new&lt;/span&gt; value&lt;br /&gt;dr[“AtomicNbr”] = &lt;span class="code-digit"&gt;1&lt;/span&gt;.&lt;span class="code-digit"&gt;00781&lt;/span&gt;;&lt;/pre&gt;  &lt;p&gt;Equivalent alternative coding methods are as follows:&lt;/p&gt;  &lt;div class="SmallText" id="premain20" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="20" src="http://www.codeproject.com/images/minus.gif" id="preimg20" width="9" height="9"&gt;&lt;span preid="20" style="margin-bottom: 0pt;" id="precollapse20"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre20" lang="cs"&gt;dt.Rows[&lt;span class="code-digit"&gt;0&lt;/span&gt;][“AtomicNbr”] = &lt;span class="code-digit"&gt;1&lt;/span&gt;.&lt;span class="code-digit"&gt;00781&lt;/span&gt;;&lt;/pre&gt;  &lt;p&gt;or&lt;/p&gt;  &lt;div class="SmallText" id="premain21" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="21" src="http://www.codeproject.com/images/minus.gif" id="preimg21" width="9" height="9"&gt;&lt;span preid="21" style="margin-bottom: 0pt;" id="precollapse21"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre21" lang="cs"&gt;dt.Rows[&lt;span class="code-digit"&gt;0&lt;/span&gt;][&lt;span class="code-digit"&gt;0&lt;/span&gt;] = &lt;span class="code-digit"&gt;1&lt;/span&gt;.&lt;span class="code-digit"&gt;00781&lt;/span&gt;;&lt;/pre&gt;  &lt;h2&gt;&lt;a name="_Toc56951011"&gt;&lt;/a&gt;&lt;a name="_Toc55609977"&gt;3.9 Fill Table using &lt;code lang="cs"&gt;LoadDataRow()&lt;/code&gt; method&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;The &lt;code lang="cs"&gt;LoadElementDataRow()&lt;/code&gt;&lt;em&gt; &lt;/em&gt;code example method in this section illustrates loading data into a table using the DataTable’s &lt;code lang="cs"&gt;LoadDataRow&lt;/code&gt; method that takes an object containing data for each cell within a row. The &lt;code lang="cs"&gt;LoadDataRow&lt;/code&gt; method is bracketed by &lt;code lang="cs"&gt;BeginLoadData()&lt;/code&gt; and &lt;code lang="cs"&gt;EndLoadData()&lt;/code&gt; methods that turn off and on event notifications and other properties related to linked tables. Using these methods can prevent unnecessary processing by event handlers that would otherwise be triggered that are discussed in the Event Handler section. Also, the &lt;code lang="cs"&gt;LoadDataRow&lt;/code&gt; method will modify an existing row if primary keys match or add the row to the Rows collection. Refer to the section on Row Versions that discusses the different versions of rows managed by the table’s class for sample code illustrating the different behaviors of the &lt;code lang="cs"&gt;LoadDataRow&lt;/code&gt; method when a table has a primary key and when it does not.&lt;/p&gt;  &lt;div class="SmallText" id="premain22" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="22" src="http://www.codeproject.com/images/minus.gif" id="preimg22" width="9" height="9"&gt;&lt;span preid="22" style="margin-bottom: 0pt;" id="precollapse22"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre22" lang="cs"&gt;&lt;span class="code-keyword"&gt;private&lt;/span&gt; DataRow LoadElementDataRow(DataTable dt,&lt;br /&gt;  &lt;span class="code-keyword"&gt;int&lt;/span&gt; AtomicNbr, &lt;span class="code-keyword"&gt;string&lt;/span&gt; Element,&lt;br /&gt;&lt;span class="code-keyword"&gt;string&lt;/span&gt; Symbol, &lt;span class="code-keyword"&gt;double&lt;/span&gt; AtomicMass)&lt;br /&gt;{&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Turns off event notifications,&lt;/span&gt;&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; index maintenance, and constraints&lt;/span&gt;&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; while loading data&lt;/span&gt;&lt;br /&gt; dt.BeginLoadData();&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Add the row values to the rows collection and&lt;/span&gt;&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; return the DataRow. If the second&lt;/span&gt;&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; argument is set to true, then dt.AcceptChanges() is called&lt;/span&gt;&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt;otherwise new rows are&lt;/span&gt;&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; marked as additions and changes to existing rows are marked as&lt;/span&gt;&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt;modifications.&lt;/span&gt;&lt;br /&gt; DataRow dr = dt.LoadDataRow(&lt;span class="code-keyword"&gt;new&lt;/span&gt; &lt;span class="code-keyword"&gt;object&lt;/span&gt;[]&lt;br /&gt;  {AtomicNbr, Element, Symbol, AtomicMass}&lt;br /&gt;  , &lt;span class="code-keyword"&gt;false&lt;/span&gt;);&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Turns on event notifications, index maintenance, and constraints&lt;/span&gt;&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; that were turned off&lt;/span&gt;&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; with the BeginLoadData() method&lt;/span&gt;&lt;br /&gt; dt.EndLoadData();&lt;br /&gt; &lt;span class="code-keyword"&gt;return&lt;/span&gt; dr; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; returns the DataRow filled&lt;/span&gt;&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; with the new values&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;  &lt;h2&gt;&lt;a name="_Toc56951012"&gt;&lt;/a&gt;&lt;a name="_Toc55609978"&gt;3.10Retrieving Table Content&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;The &lt;code lang="cs"&gt;GetTableData()&lt;/code&gt; example method retrieves the column labels and row data from an input table and formats them into a string that can be used for printing, copying to the clipboard and exporting to a tab delimited text file.&lt;/p&gt;  &lt;div class="SmallText" id="premain23" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="23" src="http://www.codeproject.com/images/minus.gif" id="preimg23" width="9" height="9"&gt;&lt;span preid="23" style="margin-bottom: 0pt;" id="precollapse23"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre23" lang="cs"&gt;&lt;span class="code-keyword"&gt;private&lt;/span&gt; &lt;span class="code-keyword"&gt;string&lt;/span&gt; GetTableData(DataTable dt)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; StringBuilder TableData = &lt;span class="code-keyword"&gt;new&lt;/span&gt; StringBuilder();&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; retrieve header row column labels&lt;/span&gt;&lt;br /&gt; TableData.AppendFormat(“Row”);&lt;br /&gt; &lt;span class="code-keyword"&gt;foreach&lt;/span&gt; (DataColumn dc &lt;span class="code-keyword"&gt;in&lt;/span&gt; dt.Columns)&lt;br /&gt; TableData.AppendFormat(“\t{&lt;span class="code-digit"&gt;0&lt;/span&gt;}”, dc.ColumnName);&lt;br /&gt; TableData.AppendFormat(“\n”);&lt;br /&gt;&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; retrieve rows&lt;/span&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;int&lt;/span&gt; j = -1;&lt;br /&gt; &lt;span class="code-keyword"&gt;foreach&lt;/span&gt; (DataRow dr &lt;span class="code-keyword"&gt;in&lt;/span&gt; dt.Rows)&lt;br /&gt; {&lt;br /&gt;   TableData.AppendFormat(“[{&lt;span class="code-digit"&gt;0&lt;/span&gt;}]”,++j);&lt;br /&gt;   &lt;span class="code-keyword"&gt;foreach&lt;/span&gt; (DataColumn dc &lt;span class="code-keyword"&gt;in&lt;/span&gt; dt.Columns)&lt;br /&gt;   {&lt;br /&gt;    TableData.AppendFormat(“\t{&lt;span class="code-digit"&gt;0&lt;/span&gt;}”, dr[dc] );&lt;br /&gt;   }&lt;br /&gt;  TableData.AppendFormat(“\n”);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;return&lt;/span&gt; TableData.ToString();&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;The output string for our element table with one row would look like the following when it is displayed in a grid format using an Excel spreadsheet or the DataGrid.&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="51"&gt; &lt;p&gt;&lt;strong&gt;Row&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;AtomicNbr&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Element&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Symbol&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="99"&gt; &lt;p&gt;&lt;strong&gt;AtomicMass&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="51"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;H&lt;/p&gt; &lt;/td&gt;  &lt;td width="99"&gt; &lt;p&gt;1.0078&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h2&gt;&lt;a name="_Toc56951013"&gt;&lt;/a&gt;&lt;a name="_Toc55609979"&gt;3.11Row Versions and Accepting/Rejecting Changes&lt;/a&gt;&lt;/h2&gt;  &lt;h3&gt;&lt;a name="_Toc56951014"&gt;&lt;/a&gt;&lt;a name="_Toc55609980"&gt;3.11.1 Methods and Enumerations&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;This is an important section to understand because the Table class maintains different states and versions of rows that can be used to provide rollback, undo and transaction logging capability. That is, this state and version information provides very powerful programmatic control over table data and UI strategies.&lt;/p&gt;  &lt;p&gt;Before discussing row states and versions there are Table and Row methods that need to be defined:&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="223"&gt; &lt;p&gt;&lt;strong&gt;Table Method&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="367"&gt; &lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="223"&gt; &lt;p&gt;&lt;code lang="cs"&gt;AcceptChanges()&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="367"&gt; &lt;p&gt;Accepts all row changes to the table. Changes can be accepted to individual rows when the DataRow &lt;code lang="cs"&gt;AcceptChanges() &lt;/code&gt;method is called. &lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="223"&gt; &lt;p&gt;&lt;code lang="cs"&gt;RejectChanges()&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="367"&gt; &lt;p&gt;Rejects all row changes to the table that have taken place since the last call to the Table or DataRow &lt;code lang="cs"&gt;AcceptChanges()&lt;/code&gt;.&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="223"&gt; &lt;p&gt;&lt;code lang="cs"&gt;GetChanges()&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="367"&gt; &lt;p&gt;Returns a table containing all rows that have been modified. This is particular useful when building transaction logs to satisfy government and corporate regulations, such as CFR21-11.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Note: If the Table &lt;/em&gt;&lt;code lang="cs"&gt;AcceptChanges&lt;/code&gt;&lt;em&gt; is called prior to &lt;/em&gt;&lt;code lang="cs"&gt;GetChanges&lt;/code&gt;&lt;em&gt; then there will be no changes and the return value is&lt;/em&gt; &lt;em&gt;null&lt;/em&gt;.&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="223"&gt; &lt;p&gt;&lt;strong&gt;Rows Method&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="367"&gt; &lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="223"&gt; &lt;p&gt;&lt;code lang="cs"&gt;Add()&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="367"&gt; &lt;p&gt;Adds a row to the rows collection&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="223"&gt; &lt;p&gt;&lt;code lang="cs"&gt;InsertAt()&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="367"&gt; &lt;p&gt;Inserts a row at a specific position in the rows collection&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="223"&gt; &lt;p&gt;&lt;code lang="cs"&gt;RemoveAt()&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="367"&gt; &lt;p&gt;Removes a row at an index from the rows collection &lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="223"&gt; &lt;p&gt;&lt;code lang="cs"&gt;AcceptChanges()&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="367"&gt; &lt;p&gt;Accepts all changes to the row including changes to the individual cells including adding and deleting the row to and from the table respectively.&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="223"&gt; &lt;p&gt;&lt;code lang="cs"&gt;RejectChanges()&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="367"&gt; &lt;p&gt;Rejects changes to the row restoring the original values&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="223"&gt; &lt;p&gt;&lt;code lang="cs"&gt;BeginEdit()&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="367"&gt; &lt;p&gt;Begins a row editing session &lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="223"&gt; &lt;p&gt;&lt;code lang="cs"&gt;CancelEdit()&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="367"&gt; &lt;p&gt;Cancels a row editing session and restores all previous values&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="223"&gt; &lt;p&gt;&lt;code lang="cs"&gt;EndEdit()&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="367"&gt; &lt;p&gt;Ends a row editing session &lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;There are four different versions of Row Collections that are automatically maintained by the Table’s object that provides extensive programmatic control over edits, deletes and inserts.&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="139"&gt; &lt;p&gt;&lt;strong&gt;DataRowVersion&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="451"&gt; &lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="139"&gt; &lt;p&gt;&lt;code lang="cs"&gt;Current&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="451"&gt; &lt;p&gt;This version contains the current set of all values contained in each table row. The current set and the default set are identical &lt;/p&gt;  &lt;ul&gt;&lt;li&gt;during modifying a row without calling &lt;code lang="cs"&gt;BeginEdit()&lt;/code&gt; &lt;/li&gt;&lt;li&gt;after &lt;code lang="cs"&gt;AcceptChanges()&lt;/code&gt; is called. &lt;/li&gt;&lt;/ul&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="139"&gt; &lt;p&gt;&lt;code lang="cs"&gt;Default&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="451"&gt; &lt;p&gt;The Default rows collection contains all of the changes. Each time a new row is created the new row is initialized to the default column values. Each time a cell value within a row is modified, the modification will be reflected in this table.&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="139"&gt; &lt;p&gt;&lt;code lang="cs"&gt;Proposed&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="451"&gt; &lt;p&gt;This version as its name implies contains only rows that have proposed changes where they are only present during a call to &lt;code lang="cs"&gt;BeginEdit()&lt;/code&gt;. When &lt;code lang="cs"&gt;EndEdit()&lt;/code&gt; is called the proposed changes are reflected in the Current &lt;code lang="cs"&gt;DataRow&lt;/code&gt;, in the Original DataRow and proposed DataRow is deleted. When the &lt;code lang="cs"&gt;CancelEdit&lt;/code&gt; is called, the proposed DataRow is deleted and the Default DataRow is changed back to the Current &lt;code lang="cs"&gt;DataRow&lt;/code&gt; values.&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="139"&gt; &lt;p&gt;&lt;code lang="cs"&gt;Original&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="451"&gt; &lt;p&gt;The Original Rows collection is updated each time &lt;code lang="cs"&gt;AcceptChanges()&lt;/code&gt; is called. These values are used when &lt;code lang="cs"&gt;RejectChanges()&lt;/code&gt; and &lt;code lang="cs"&gt;CancelEdit()&lt;/code&gt; are called to return the values back to the state before any changes occurred since the last call to &lt;code lang="cs"&gt;AcceptChanges()&lt;/code&gt;.&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="139"&gt; &lt;p&gt;&lt;strong&gt;RowState&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="451"&gt; &lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="139"&gt; &lt;p&gt;&lt;code lang="cs"&gt;Added&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="451"&gt; &lt;p&gt;The row is marked as &lt;em&gt;Added&lt;/em&gt; when a row is added or inserted to the Rows Collection and before an &lt;code lang="cs"&gt;AcceptChanges()&lt;/code&gt; method is called.&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="139"&gt; &lt;p&gt;&lt;code lang="cs"&gt;Deleted&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="451"&gt; &lt;p&gt;After &lt;code lang="cs"&gt;AcceptChanges()&lt;/code&gt; is called the row is marked as &lt;em&gt;Deleted&lt;/em&gt; when any of the following is performed:&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;code lang="cs"&gt;dr.Delete() &lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code lang="cs"&gt;dt.Rows.RemoveAt(index)&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code lang="cs"&gt;dt.Rows.Remove(dr)&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="139"&gt; &lt;p&gt;&lt;code lang="cs"&gt;Detached&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="451"&gt; &lt;p&gt;Before &lt;code lang="cs"&gt;AcceptChanges()&lt;/code&gt; is called the row is marked as &lt;em&gt;Detached&lt;/em&gt; when any of the following is performed:&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;code lang="cs"&gt;dr.Delete() &lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code lang="cs"&gt;dt.Rows.RemoveAt(index)&lt;/code&gt; &lt;/li&gt;&lt;li&gt;&lt;code lang="cs"&gt;dt.Rows.Remove(dr)&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="139"&gt; &lt;p&gt;&lt;code lang="cs"&gt;Modified&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="451"&gt; &lt;p&gt;After &lt;code lang="cs"&gt;AcceptChanges()&lt;/code&gt; is called any row cell value that is changed causes the row to be marked as &lt;em&gt;Modified&lt;/em&gt;. &lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="139"&gt; &lt;p&gt;&lt;code lang="cs"&gt;Unchanged&lt;/code&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="451"&gt; &lt;p&gt;After &lt;code lang="cs"&gt;AcceptChanges()&lt;/code&gt; is called the row or all rows are marked as &lt;em&gt;Unchanged&lt;/em&gt; depending upon whether it is a DataRow &lt;code lang="cs"&gt;AcceptChanges()&lt;/code&gt; call or Table &lt;code lang="cs"&gt;AcceptChanges()&lt;/code&gt; call.&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;div class="SmallText" id="premain24" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="24" src="http://www.codeproject.com/images/minus.gif" id="preimg24" width="9" height="9"&gt;&lt;span preid="24" style="margin-bottom: 0pt;" id="precollapse24"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre24" lang="cs"&gt;DataTable dt = &lt;span class="code-keyword"&gt;new&lt;/span&gt; DataTable(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Elements"&lt;/span&gt;);&lt;br /&gt;DataColumn AtomicNbr = &lt;span class="code-keyword"&gt;new&lt;/span&gt; DataColumn(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;AtomicNbr"&lt;/span&gt;,&lt;br /&gt;System.Type.GetType(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;System.Int32"&lt;/span&gt;));&lt;br /&gt;AtomicNbr.DefaultValue=0;&lt;br /&gt;dt.Columns.Add(AtomicNbr);&lt;br /&gt;DataColumn Element = &lt;span class="code-keyword"&gt;new&lt;/span&gt; DataColumn(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Element"&lt;/span&gt;,&lt;br /&gt;System.Type.GetType(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;System.String"&lt;/span&gt;));&lt;br /&gt;Element.DefaultValue= &lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Element"&lt;/span&gt;;&lt;br /&gt;dt.Columns.Add(Element);&lt;br /&gt;DataRow dr;&lt;/pre&gt;  &lt;h3&gt;&lt;a name="_Toc56951015"&gt;&lt;/a&gt;&lt;a name="_Toc55609981"&gt;3.11.2 Sample 1 – Row States&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;This section shows the different row states and the conditions for them.&lt;/p&gt;  &lt;div class="SmallText" id="premain25" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="25" src="http://www.codeproject.com/images/minus.gif" id="preimg25" width="9" height="9"&gt;&lt;span preid="25" style="margin-bottom: 0pt;" id="precollapse25"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre25" lang="cs"&gt;dr = dt.NewRow();&lt;br /&gt;dr[Element]=&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Hydrogen"&lt;/span&gt;;&lt;br /&gt;dr[AtomicNbr]= &lt;span class="code-digit"&gt;1&lt;/span&gt;;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; NewRow Before Add: RowState=Detached&lt;/span&gt;&lt;br /&gt;dt.Rows.Add(dr);&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; NewRow After Add: RowState=Added&lt;/span&gt;&lt;br /&gt;dt.Rows[&lt;span class="code-digit"&gt;0&lt;/span&gt;].AcceptChanges();&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt;NewRow After AcceptChanges: RowState=Unchanged&lt;/span&gt;&lt;br /&gt;dt.Rows.RemoveAt(&lt;span class="code-digit"&gt;0&lt;/span&gt;);&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; note that the row is marked as Detached when&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; RemoveAt() or Remove() is used&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt;NewRow After RemoveAt: RowState=Detached&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Add the row back, accept the changes and then delete the row&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; note that the row state is now marked as deleted when Delete()&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; if Delete() is called prior to the row being&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; added then the row is marked as Detached.&lt;/span&gt;&lt;br /&gt;dt.Rows.Add(dr);&lt;br /&gt;dt.AcceptChanges();&lt;br /&gt;dr.Delete();&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; NewRow After Delete: &lt;RowState=Deleted&gt;&lt;/span&gt;&lt;/pre&gt;  &lt;p&gt;The following code examples will illustrate the above method functionality. After each section of code will be four tables, one each for each type of DataRowVersion, that will show whether the version contains a row and if so their respective values.&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="499"&gt; &lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="499"&gt; &lt;ul type="disc"&gt;&lt;li&gt;Rows that do not exist (designated with a ‘No’ value under column ‘Has Versions’) for a particular RowState version are added or included for readability and clarity. That is, if all the rows in a version table were listed, these would not be in the Table Rows collection.&lt;/li&gt;&lt;/ul&gt;  &lt;ul type="disc"&gt;&lt;li&gt;The presentation schema is from code Sample 2 to Sample N where each successive code Sample uses the results from the previous Sample. All changes that occur to the version tables for Sample code section are designated in &lt;strong&gt;bold red&lt;/strong&gt;.&lt;/li&gt;&lt;/ul&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h3&gt;&lt;a name="_Toc56951016"&gt;&lt;/a&gt;&lt;a name="_Toc55609982"&gt;3.11.3 Sample 2 – Initial Loading of Table&lt;/a&gt;&lt;/h3&gt;  &lt;div class="SmallText" id="premain26" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="26" src="http://www.codeproject.com/images/minus.gif" id="preimg26" width="9" height="9"&gt;&lt;span preid="26" style="margin-bottom: 0pt;" id="precollapse26"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre26" lang="cs"&gt;dr = dt.NewRow();&lt;br /&gt;dr[Element]=&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Hydrogen"&lt;/span&gt;;&lt;br /&gt;dr[AtomicNbr]= &lt;span class="code-digit"&gt;1&lt;/span&gt;;&lt;br /&gt;dt.Rows.Add(dr);&lt;br /&gt;dr = dt.NewRow();&lt;br /&gt;dr[Element]=&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Helium"&lt;/span&gt;;&lt;br /&gt;dr[AtomicNbr]= &lt;span class="code-digit"&gt;2&lt;/span&gt;;&lt;br /&gt;dt.Rows.Add(dr);&lt;br /&gt;dr = dt.NewRow();&lt;br /&gt;dr[Element]=&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Lithium"&lt;/span&gt;;&lt;br /&gt;dr[AtomicNbr]= &lt;span class="code-digit"&gt;3&lt;/span&gt;;&lt;br /&gt;dt.Rows.Add(dr);&lt;br /&gt;dr = dt.NewRow();&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; this row contains default values&lt;/span&gt;&lt;br /&gt;dt.Rows.Add(dr);&lt;/pre&gt;  &lt;p&gt;Row 0 has only an Original Version and it is marked as Deleted. The Current and Default versions are identical with the four new rows being marked as Added. The Proposed version table does not contain any values.&lt;/p&gt;  &lt;h3&gt;Current Version&lt;/h3&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h3&gt;Default Version&lt;/h3&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h3&gt;Original Version&lt;/h3&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Deleted&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h3&gt;Proposed Version&lt;/h3&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h3&gt;&lt;a name="_Toc56951017"&gt;&lt;/a&gt;&lt;a name="_Toc55609983"&gt;3.11.4 Sample 3 – DataRow AcceptChanges&lt;/a&gt;&lt;/h3&gt;  &lt;div class="SmallText" id="premain27" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="27" src="http://www.codeproject.com/images/minus.gif" id="preimg27" width="9" height="9"&gt;&lt;span preid="27" style="margin-bottom: 0pt;" id="precollapse27"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre27" lang="cs"&gt;dt.Rows[&lt;span class="code-digit"&gt;0&lt;/span&gt;].AcceptChanges();&lt;br /&gt;dt.Rows[&lt;span class="code-digit"&gt;1&lt;/span&gt;].AcceptChanges();&lt;/pre&gt;  &lt;p&gt;After the &lt;code lang="cs"&gt;Rows[&lt;span class="code-digit"&gt;0&lt;/span&gt;].AcceptChanges()&lt;/code&gt; was called, the row that was marked deleted, row 0 in the above version tables, has been deleted from all versions and all other rows have new indices. The next &lt;code lang="cs"&gt;AcceptChanges() &lt;/code&gt;command references row 1 in the newly ordered Rows Collection. In this case, the Row State is marked as Unchanged in versions Current, Default and Original. In the Original version there is only one row and it corresponds to Row 1 that was accepted. The Proposed version table does not contain any values.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Current Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;[0]&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;[1]&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;[2]&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;[3]&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Default Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;[0]&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;[1]&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;[2]&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;[3]&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Original Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;[0]&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;[1]&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Helium&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;[2]&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;[3]&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Proposed Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;[0]&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;[1]&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;[2]&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;[3]&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h3&gt;&lt;a name="_Toc56951018"&gt;&lt;/a&gt;&lt;a name="_Toc55609984"&gt;3.11.5 Sample 4 – Table AcceptChanges&lt;/a&gt;&lt;/h3&gt;  &lt;div class="SmallText" id="premain28" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="28" src="http://www.codeproject.com/images/minus.gif" id="preimg28" width="9" height="9"&gt;&lt;span preid="28" style="margin-bottom: 0pt;" id="precollapse28"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre28" lang="cs"&gt;dt.AcceptChanges();&lt;/pre&gt;  &lt;p&gt;After the &lt;code lang="cs"&gt;Table.AcceptChanges()&lt;/code&gt; is called, all remaining rows are marked Unchanged in the Current, Default and Original Version tables and the Original version table is identical to the Current and Default version tables. The Proposed version table does not contain any rows.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Current Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Hydrogen&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Lithium&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Element&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Default Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Hydrogen&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Lithium&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Element&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Original Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Hydrogen&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Lithium&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Element&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Proposed Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h3&gt;&lt;a name="_Toc56951019"&gt;&lt;/a&gt;&lt;a name="_Toc55609985"&gt;3.11.6 Sample 5 – DataRow BeginEdit&lt;/a&gt;&lt;/h3&gt;  &lt;div class="SmallText" id="premain29" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="29" src="http://www.codeproject.com/images/minus.gif" id="preimg29" width="9" height="9"&gt;&lt;span preid="29" style="margin-bottom: 0pt;" id="precollapse29"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre29" lang="cs"&gt;dt.Rows[&lt;span class="code-digit"&gt;1&lt;/span&gt;].BeginEdit();&lt;br /&gt;dt.Rows[&lt;span class="code-digit"&gt;1&lt;/span&gt;][&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Element"&lt;/span&gt;]= &lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Helium"&lt;/span&gt;;&lt;br /&gt;dt.Rows[&lt;span class="code-digit"&gt;1&lt;/span&gt;][&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;AtomicNbr"&lt;/span&gt;]= &lt;span class="code-digit"&gt;222&lt;/span&gt;;&lt;/pre&gt;  &lt;p&gt;The above code begins an editing session on row 1 and the new values are reflected in the Default version table and values now appear in the Proposed version table. All other table version entries remain unchanged.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Current Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Default Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;222&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Helium&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Original Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Proposed Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;222&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Helium&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h3&gt;&lt;a name="_Toc56951020"&gt;&lt;/a&gt;&lt;a name="_Toc55609986"&gt;3.11.7 Sample 6 – DataRow CancelEdit&lt;/a&gt;&lt;/h3&gt;  &lt;div class="SmallText" id="premain30" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="30" src="http://www.codeproject.com/images/minus.gif" id="preimg30" width="9" height="9"&gt;&lt;span preid="30" style="margin-bottom: 0pt;" id="precollapse30"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre30" lang="cs"&gt;dt.Rows[&lt;span class="code-digit"&gt;1&lt;/span&gt;].CancelEdit();&lt;/pre&gt;  &lt;p&gt;The &lt;code lang="cs"&gt;CancelEdit() &lt;/code&gt;command returns the default values back to the Original state and clears out the Proposed values from row 1 in the Proposed version table.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Current Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Default Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Helium&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Original Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Proposed Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;No&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h3&gt;&lt;a name="_Toc56951021"&gt;&lt;/a&gt;&lt;a name="_Toc55609987"&gt;3.11.8 Sample 7 – DataRow BeginEdit – Example 2&lt;/a&gt;&lt;/h3&gt;  &lt;div class="SmallText" id="premain31" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="31" src="http://www.codeproject.com/images/minus.gif" id="preimg31" width="9" height="9"&gt;&lt;span preid="31" style="margin-bottom: 0pt;" id="precollapse31"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre31" lang="cs"&gt;dt.Rows[&lt;span class="code-digit"&gt;3&lt;/span&gt;].BeginEdit();&lt;/pre&gt;  &lt;p&gt;The &lt;code lang="cs"&gt;BeginEdit()&lt;/code&gt; method initializes the Proposed row 3 with default values. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Current Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Default Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Original Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Proposed Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Element&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h3&gt;&lt;a name="_Toc56951022"&gt;&lt;/a&gt;&lt;a name="_Toc55609988"&gt;3.11.9 Sample 8 – DataRow Change values – Example 2&lt;/a&gt;&lt;/h3&gt;  &lt;div class="SmallText" id="premain32" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="32" src="http://www.codeproject.com/images/minus.gif" id="preimg32" width="9" height="9"&gt;&lt;span preid="32" style="margin-bottom: 0pt;" id="precollapse32"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre32" lang="cs"&gt;dt.Rows[&lt;span class="code-digit"&gt;3&lt;/span&gt;][&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Element"&lt;/span&gt;]=&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Carbon"&lt;/span&gt;;&lt;br /&gt;dt.Rows[&lt;span class="code-digit"&gt;3&lt;/span&gt;][&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;AtomicNbr"&lt;/span&gt;]= &lt;span class="code-digit"&gt;12&lt;/span&gt;;&lt;/pre&gt;  &lt;p&gt;The Default and Proposed row 3 values have been changed to reflect Carbon and 12. All other rows in all versions remain unchanged.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Current Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Default Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;12&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Carbon&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Original Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Proposed Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;12&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Carbon&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h3&gt;&lt;a name="_Toc56951023"&gt;&lt;/a&gt;&lt;a name="_Toc55609989"&gt;3.11.10 Sample 9 – DataRow EndEdit – Modified Rows&lt;/a&gt;&lt;/h3&gt;  &lt;div class="SmallText" id="premain33" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="33" src="http://www.codeproject.com/images/minus.gif" id="preimg33" width="9" height="9"&gt;&lt;span preid="33" style="margin-bottom: 0pt;" id="precollapse33"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre33" lang="cs"&gt;dt.Rows[&lt;span class="code-digit"&gt;3&lt;/span&gt;].EndEdit();&lt;br /&gt;dt.Rows[&lt;span class="code-digit"&gt;0&lt;/span&gt;][&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Element"&lt;/span&gt;] = &lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Oxygen"&lt;/span&gt;;&lt;br /&gt;dt.Rows[&lt;span class="code-digit"&gt;0&lt;/span&gt;][&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;AtomicNbr"&lt;/span&gt;] = &lt;span class="code-digit"&gt;8&lt;/span&gt;;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Add a new row.&lt;/span&gt;&lt;br /&gt;dr = dt.NewRow();&lt;br /&gt;dt.Rows.Add(dr);&lt;/pre&gt;  &lt;p&gt;After &lt;code lang="cs"&gt;EndEdit()&lt;/code&gt; is called, the Current and Default versions for row 3 are updated and marked as Modified. The Original version for row 3 still retains the original values before the changes and is marked as Modified.&lt;/p&gt;  &lt;p&gt;The next two lines assign “Oxygen” and its atomic number to row 0 and these values are reflected in the Current and Default versions, which are also marked as Modified. The Original version for row 0 remains unchanged.&lt;/p&gt;  &lt;p&gt;The next two lines adds a new row to the Current and Default version tables initialized with default values and marked as Added. Note that the new row does not appear in the Original version table.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Current Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Modified&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;8&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Oxygen&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Modified&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;12&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Carbon&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Added&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Element&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Default Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Modified&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;8&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Oxygen&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Modified&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;12&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Carbon&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Added&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Element&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Original Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Modified&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Modified&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Proposed Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;No&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h3&gt;&lt;a name="_Toc56951024"&gt;&lt;/a&gt;&lt;a name="_Toc55609990"&gt;3.11.11 Sample 10 – DataRow AcceptChanges of Modified Rows&lt;/a&gt;&lt;/h3&gt;  &lt;div class="SmallText" id="premain34" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="34" src="http://www.codeproject.com/images/minus.gif" id="preimg34" width="9" height="9"&gt;&lt;span preid="34" style="margin-bottom: 0pt;" id="precollapse34"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre34" lang="cs"&gt;dt.Rows[&lt;span class="code-digit"&gt;3&lt;/span&gt;].AcceptChanges();&lt;/pre&gt;  &lt;p&gt;The DataRow &lt;code lang="cs"&gt;AcceptChanges()&lt;/code&gt; for row 3 causes the corresponding row in the Current and Default version tables to be marked as Unchanged and the Original version table now contains the same row values. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Current Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Modified&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;8&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Oxygen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;12&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Carbon&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Default Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Modified&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;8&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Oxygen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;12&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Carbon&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Original Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Modified&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;12&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Carbon&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Proposed Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h3&gt;&lt;a name="_Toc56951025"&gt;&lt;/a&gt;&lt;a name="_Toc55609991"&gt;3.11.12 Sample 11 – DataRow RejectChanges&lt;/a&gt;&lt;/h3&gt;  &lt;div class="SmallText" id="premain35" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="35" src="http://www.codeproject.com/images/minus.gif" id="preimg35" width="9" height="9"&gt;&lt;span preid="35" style="margin-bottom: 0pt;" id="precollapse35"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre35" lang="cs"&gt;dt.Rows[&lt;span class="code-digit"&gt;0&lt;/span&gt;].RejectChanges();&lt;/pre&gt;  &lt;p&gt;Calling the DataRow &lt;code lang="cs"&gt;RejectChanges()&lt;/code&gt; method for row 0 causes the corresponding row values for the Current and Default tables to revert to the Original version values and three tables, Current, Default and Original, have the Row State for row 0 marked as unchanged.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Current Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Hydrogen&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;12&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Carbon&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Default Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Unchanged&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Hydrogen&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;12&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Carbon&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Original Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;12&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Carbon&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Proposed Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h3&gt;&lt;a name="_Toc56951026"&gt;&lt;/a&gt;&lt;a name="_Toc55609992"&gt;3.11.13 Sample 12 – LoadDataRow without table having primary key&lt;/a&gt;&lt;/h3&gt;  &lt;div class="SmallText" id="premain36" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="36" src="http://www.codeproject.com/images/minus.gif" id="preimg36" width="9" height="9"&gt;&lt;span preid="36" style="margin-bottom: 0pt;" id="precollapse36"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre36" lang="cs"&gt;dt.BeginLoadData();&lt;br /&gt;dt.LoadDataRow(&lt;span class="code-keyword"&gt;new&lt;/span&gt; &lt;span class="code-keyword"&gt;object&lt;/span&gt;[]{&lt;span class="code-digit"&gt;1&lt;/span&gt;,&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Deuterium"&lt;/span&gt;}, &lt;span class="code-keyword"&gt;false&lt;/span&gt;);&lt;br /&gt;dt.EndLoadData();&lt;/pre&gt;  &lt;p&gt;If a table does not have a primary key then the LoadDataRow method will create a new row and fill it with values in the object array. Looking at rows 0 and 5 in the Current and Default version tables, they both have the same atomic number, but different element names. Also, Row 5 is marked as being &lt;em&gt;Added&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Current Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;12&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Carbon&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[5]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Added&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Deuterium&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Default Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;12&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Carbon&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Added&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[5]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Added&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Deuterium&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Original Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;12&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Carbon&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[5]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Proposed Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[5]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h3&gt;&lt;a name="_Toc56951027"&gt;&lt;/a&gt;&lt;a name="_Toc55609993"&gt;3.11.14 Sample 13 – LoadDataRow with table having primary key&lt;/a&gt;&lt;/h3&gt;  &lt;div class="SmallText" id="premain37" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="37" src="http://www.codeproject.com/images/minus.gif" id="preimg37" width="9" height="9"&gt;&lt;span preid="37" style="margin-bottom: 0pt;" id="precollapse37"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre37" lang="cs"&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; must delete the row with a duplicate&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; AtomicNbr in order to create&lt;/span&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; a primary key.&lt;/span&gt;&lt;br /&gt;dt.Rows.RemoveAt(&lt;span class="code-digit"&gt;5&lt;/span&gt;);&lt;br /&gt;dt.AcceptChanges();&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Create a primary key and load the new object array data.&lt;/span&gt;&lt;br /&gt;dt.PrimaryKey = &lt;span class="code-keyword"&gt;new&lt;/span&gt; DataColumn[] {dt.Columns[&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;AtomicNbr"&lt;/span&gt;]};&lt;br /&gt;dt.BeginLoadData();&lt;br /&gt;dt.LoadDataRow(&lt;span class="code-keyword"&gt;new&lt;/span&gt; &lt;span class="code-keyword"&gt;object&lt;/span&gt;[]{&lt;span class="code-digit"&gt;1&lt;/span&gt;,&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Deuterium"&lt;/span&gt;}, &lt;span class="code-keyword"&gt;false&lt;/span&gt;);&lt;br /&gt;dt.EndLoadData();&lt;/pre&gt;  &lt;p&gt;If a table has a primary key then the &lt;code lang="cs"&gt;LoadDataRow&lt;/code&gt; method will modify the data in the row if the primary keys match or else it will append the row to the table. Looking at row 0 in the Current and Default version tables, the element name has been changed from Hydrogen to Deuterium. In the three version tables Current, Default and Original row 0 is now marked as being &lt;em&gt;Modified&lt;/em&gt;. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Current Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Modified&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Deuterium&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;12&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Carbon&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Default Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Modified&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Deuterium&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;12&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Carbon&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Original Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;&lt;strong&gt;Modified&lt;/strong&gt;&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;1&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Hydrogen&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;2&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Helium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;3&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Lithium&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;12&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Carbon&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Yes&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Unchanged&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;0&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;Proposed Version&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;table border="1" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;Row&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Has Versions&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Row State&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;AtomicNbr&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;Element&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[0]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[1]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[2]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[3]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td width="118"&gt; &lt;p&gt;[4]&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt; &lt;p&gt;No&lt;/p&gt; &lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td width="118"&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h3&gt;&lt;a name="_Toc56951028"&gt;&lt;/a&gt;&lt;a name="_Toc55609994"&gt;3.11.15 Sample Code for Obtaining Version and State Information&lt;/a&gt;&lt;/h3&gt;  &lt;p&gt;The above tables were generated using the following procedure.&lt;/p&gt;  &lt;div class="SmallText" id="premain38" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="38" src="http://www.codeproject.com/images/minus.gif" id="preimg38" width="9" height="9"&gt;&lt;span preid="38" style="margin-bottom: 0pt;" id="precollapse38"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre38" lang="cs"&gt;&lt;span class="code-keyword"&gt;static&lt;/span&gt; &lt;span class="code-keyword"&gt;void&lt;/span&gt; PrintRowVersions(DataTable dt)&lt;br /&gt;{&lt;br /&gt; DataRowVersion[] rowVer = &lt;span class="code-keyword"&gt;new&lt;/span&gt; DataRowVersion[&lt;span class="code-digit"&gt;4&lt;/span&gt;];&lt;br /&gt; rowVer[&lt;span class="code-digit"&gt;0&lt;/span&gt;] = DataRowVersion.Current;&lt;br /&gt; rowVer[&lt;span class="code-digit"&gt;1&lt;/span&gt;] = DataRowVersion.Default;&lt;br /&gt; rowVer[&lt;span class="code-digit"&gt;2&lt;/span&gt;] = DataRowVersion.Original;&lt;br /&gt; rowVer[&lt;span class="code-digit"&gt;3&lt;/span&gt;] = DataRowVersion.Proposed;&lt;br /&gt; StringBuilder TableData = &lt;span class="code-keyword"&gt;new&lt;/span&gt; StringBuilder();&lt;br /&gt; &lt;span class="code-keyword"&gt;for&lt;/span&gt;(&lt;span class="code-keyword"&gt;int&lt;/span&gt; i=0; i&lt;rowVer.Length; i++)&lt;br /&gt; {&lt;br /&gt;   &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Print the value of each column in each row.&lt;/span&gt;&lt;br /&gt;   TableData.AppendFormat(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;{0} Version\n"&lt;/span&gt;, rowVer[i].ToString());&lt;br /&gt;   &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; retrieve header row column labels&lt;/span&gt;&lt;br /&gt;   TableData.AppendFormat(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;Row\tHas Versions\tRow State"&lt;/span&gt;);&lt;br /&gt;   &lt;span class="code-keyword"&gt;foreach&lt;/span&gt; (DataColumn dc &lt;span class="code-keyword"&gt;in&lt;/span&gt; dt.Columns)&lt;br /&gt;     TableData.AppendFormat(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;\t{0}"&lt;/span&gt;, dc.ColumnName);&lt;br /&gt;   TableData.AppendFormat(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;\n"&lt;/span&gt;);&lt;br /&gt;   &lt;span class="code-keyword"&gt;int&lt;/span&gt; n=-1;&lt;br /&gt;   &lt;span class="code-keyword"&gt;foreach&lt;/span&gt;(DataRow row &lt;span class="code-keyword"&gt;in&lt;/span&gt; dt.Rows )&lt;br /&gt;   {&lt;br /&gt;     n++;&lt;br /&gt;     &lt;span class="code-keyword"&gt;if&lt;/span&gt; (row.HasVersion(rowVer[i]) )&lt;br /&gt;     {&lt;br /&gt;       &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Print the specified version of the row's value.&lt;/span&gt;&lt;br /&gt;       TableData.AppendFormat(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;[{0}]\tYes\t{1}"&lt;/span&gt;,&lt;br /&gt;       n.ToString(), row.RowState.ToString());&lt;br /&gt;       &lt;span class="code-keyword"&gt;foreach&lt;/span&gt; (DataColumn dc &lt;span class="code-keyword"&gt;in&lt;/span&gt; dt.Columns)&lt;br /&gt;       {&lt;br /&gt;          TableData.AppendFormat(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;\t{0}"&lt;/span&gt;, row[dc,rowVer[i]]);&lt;br /&gt;       }&lt;br /&gt;       TableData.AppendFormat(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;\n"&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;    &lt;span class="code-keyword"&gt;else&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;       TableData.AppendFormat(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;[{0}]\tNo\t"&lt;/span&gt;, n.ToString());&lt;br /&gt;       &lt;span class="code-keyword"&gt;for&lt;/span&gt;(&lt;span class="code-keyword"&gt;int&lt;/span&gt; j=0; j&lt;dt.Columns.Count; j++)&lt;br /&gt;        TableData.AppendFormat(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;\t "&lt;/span&gt;);&lt;br /&gt;       TableData.AppendFormat(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;\n"&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  TableData.AppendFormat(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;\n"&lt;/span&gt;);&lt;br /&gt; }&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; output string data to a text file using a StreamWriter&lt;/span&gt;&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; StreamWriter sw = new StreamWriter("c:\RowVersions.txt");&lt;/span&gt;&lt;br /&gt; sw.Write(TableData.ToString());&lt;br /&gt; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; sw.Close();&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;  &lt;h2&gt;&lt;a name="_Toc56951029"&gt;3.12Handling DataTable Errors&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;A DataTable can be checked to determine if it contains any rows with errors by examining the Table’s &lt;code lang="cs"&gt;HasErrors&lt;/code&gt; property value. The following code illustrates how to isolate the rows and their columns with errors. &lt;/p&gt;  &lt;div class="SmallText" id="premain39" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="39" src="http://www.codeproject.com/images/minus.gif" id="preimg39" width="9" height="9"&gt;&lt;span preid="39" style="margin-bottom: 0pt;" id="precollapse39"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre39" lang="cs"&gt;&lt;span class="code-keyword"&gt;if&lt;/span&gt; (dt.HasErrors)&lt;br /&gt;{ &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Errors have occurred in rows in table dt&lt;/span&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;foreach&lt;/span&gt; (DataRow dr &lt;span class="code-keyword"&gt;in&lt;/span&gt; dt.Rows)&lt;br /&gt; {&lt;br /&gt;  &lt;span class="code-keyword"&gt;if&lt;/span&gt;(dr.HasErrors)&lt;br /&gt;  {&lt;br /&gt;   &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Row has errors&lt;/span&gt;&lt;br /&gt;   &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; GetColumnsInError() returns an array of&lt;/span&gt;&lt;br /&gt;   &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; DataColumns that contain errors&lt;/span&gt;&lt;br /&gt;   &lt;span class="code-keyword"&gt;foreach&lt;/span&gt;(DataColumn dc &lt;span class="code-keyword"&gt;in&lt;/span&gt; dr.GetColumnsInError())&lt;br /&gt;   {&lt;br /&gt;     &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; GetColumnError returns a description of the Column error&lt;/span&gt;&lt;br /&gt;     MessageBox.Show(dr.GetColumnError(dc.Ordinal));&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;  &lt;h2&gt;&lt;a name="_Toc56951030"&gt;3.13DataTable Events&lt;/a&gt;&lt;/h2&gt;  &lt;p&gt;The following code provides an example of adding a DataTable column changed event handler and the code within the handler illustrates some techniques for processing the new column values.&lt;/p&gt;  &lt;div class="SmallText" id="premain40" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="40" src="http://www.codeproject.com/images/minus.gif" id="preimg40" width="9" height="9"&gt;&lt;span preid="40" style="margin-bottom: 0pt;" id="precollapse40"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre40" lang="cs"&gt;dt.ColumnChanged += &lt;span class="code-keyword"&gt;new&lt;/span&gt; DataColumnChangeEventHandler&lt;br /&gt; (&lt;span class="code-keyword"&gt;this&lt;/span&gt;.SampleForm_ColumnChanged);&lt;br /&gt;&lt;span class="code-keyword"&gt;private&lt;/span&gt; &lt;span class="code-keyword"&gt;void&lt;/span&gt; SampleForm_ColumnChanged(&lt;span class="code-keyword"&gt;object&lt;/span&gt; sender,&lt;br /&gt; System.Data.DataColumnChangeEventArgs e)&lt;br /&gt;{&lt;br /&gt;&lt;span class="code-keyword"&gt;if&lt;/span&gt;(e.Column.Ordinal &lt;op&gt; …)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; could perform validation checks such as range values&lt;/span&gt;&lt;br /&gt;  &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; or formatting or other types of &lt;/span&gt;&lt;br /&gt;  &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt;processing on the changed column.&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;span class="code-keyword"&gt;if&lt;/span&gt;(e.Row.HasErrors)&lt;br /&gt;{&lt;br /&gt;  &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; clear the error&lt;/span&gt;&lt;br /&gt;  e.Row.SetColumnError(e.Column, &lt;span class="code-keyword"&gt;string&lt;/span&gt;.Empty);&lt;br /&gt;  &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; check to see if row has any more errors&lt;/span&gt;&lt;br /&gt;  DataColumn [] dcErrors = e.Row.GetColumnsInError();&lt;br /&gt;  &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; if there are no more errors then clear the row error flag.&lt;/span&gt;&lt;br /&gt;  &lt;span class="code-keyword"&gt;if&lt;/span&gt;(dcErrors.Length == &lt;span class="code-digit"&gt;0&lt;/span&gt;)&lt;br /&gt;  e.Row.ClearErrors();&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/864116869953733620-8673817559168496799?l=narulaamitsk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://narulaamitsk.blogspot.com/feeds/8673817559168496799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=864116869953733620&amp;postID=8673817559168496799' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/8673817559168496799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/8673817559168496799'/><link rel='alternate' type='text/html' href='http://narulaamitsk.blogspot.com/2009/06/1-introduction-purpose-of-this-document.html' title=''/><author><name>Amit Narula</name><uri>http://www.blogger.com/profile/03373886236261160868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_KIFo2nRsLTc/SfIq-GgjUkI/AAAAAAAACCo/bBDItRMEB6s/S220/DSCF1775.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-864116869953733620.post-7723321109309155792</id><published>2009-06-15T00:06:00.000-07:00</published><updated>2009-06-15T00:07:58.871-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Secure web applications'/><title type='text'>How To Make Your Website More (McAfee) Secure</title><content type='html'>&lt;h2 style="text-align: justify;"&gt;Introduction&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;Recently one of my clients requested, after a critical attack on the server where an application was running, to make sure that the application is secured in all perspectives. We chose McAfee to ensure that the website is 100% hacker proof. After a thorough Application Scan, Network Scan, and PCI Scan, McAfee found out several vulnerabilities in the Website, and I thought some of them exist in most of the websites we make. So here is a brief list and solutions we have found out to make a website 100% McAfee Secured and PCI Compliant. &lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;Before we delve into the technical details, I want to clarify what this article covers and what it does not, better not to create any false expectations. This article is solely based on my experience while solving the vulnerabilities, and I have presented them likewise. As several of the fixes require tweaks in registry, make sure to back the registry up, and change anything at your own risk. &lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;Following are the most important vulnerabilities that were reported by McAfee:&lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;h2 style="text-align: justify;"&gt;Vulnerability 1&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;h3 style="text-align: justify;"&gt;Vulnerability Name:  Microsoft .NET Custom Errors Not Set&lt;/h3&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;h4 style="text-align: justify;"&gt;Description &lt;/h4&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;This is when the custom error page is not set for an application. We generally use the &lt;em&gt;web.config&lt;/em&gt; to specify the Error Page. But McAfee requires it to be done both ways.&lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;h4 style="text-align: justify;"&gt;Solution&lt;/h4&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;In order to fix this vulnerability the error pages must be set from the IIS. The steps are as follows:&lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Go to IIS Manager &lt;/li&gt;&lt;li&gt;Right click on the project name that has to be McAfee Secured &lt;/li&gt;&lt;li&gt;Click Properties &lt;/li&gt;&lt;li&gt;In the Properties Box, click on the “Custom Errors” tab and the following window appears:  &lt;p&gt;&lt;img alt="Fig1.jpg" src="http://www.codeproject.com/KB/aspnet/MakeWebsiteMcAfeeSecured/Fig1.jpg" width="475" height="467" /&gt; &lt;/p&gt; &lt;/li&gt;&lt;li&gt;Highlight any one of the error types and click on edit properties and a small window appears where the custom error page can be specified. &lt;p&gt;&lt;img alt="Fig2.png" src="http://www.codeproject.com/KB/aspnet/MakeWebsiteMcAfeeSecured/Fig2.png" width="396" height="216" /&gt; &lt;/p&gt; &lt;/li&gt;&lt;li&gt;Click on OK button in both this and its parent window. &lt;/li&gt;&lt;li&gt;If even one error page is specified for any one error, McAfee considers this a vulnerability no more. &lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;h2 style="text-align: justify;"&gt;Vulnerability 2&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;h3 style="text-align: justify;"&gt;Vulnerability Name: Allow All Policy in crossdomain.xml&lt;/h3&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;h4 style="text-align: justify;"&gt;Description&lt;/h4&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;If a website uses several flash videos and content and other websites use them in their websites, the &lt;em&gt;crossdomain.xml&lt;/em&gt; comes into play. This XML file sets the policy about who can use the content in their websites in terms of domain name. It has a key called – &lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;div class="SmallText" id="premain0" style="width: 100%; cursor: pointer; text-align: justify;"&gt;&lt;img preid="0" src="http://www.codeproject.com/images/minus.gif" id="preimg0" width="9" height="9" /&gt;&lt;span preid="0" style="margin-bottom: 0pt;" id="precollapse0"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;pre style="margin-top: 0pt;" id="pre0" lang="text"&gt;&lt;allow-access-from domain="*"&gt;&lt;/pre&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;According to McAfee, this poses a serious threat of hack attack to the website.&lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;h4 style="text-align: justify;"&gt;Solution&lt;/h4&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;It is very confusing how McAfee scans the file, because even if the file is removed from the root (wwwroot), and a copy of the file still exists in any place of the whole server, McAfee still finds that and gives an alert. The best solution is to Edit each and every occurrence of that file in the whole server and remove all stars (*) and give specific domain names from which the videos will be accessed. If not required, it is best to completely delete the file.&lt;br /&gt;So the edited file will look like:  &lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;div class="SmallText" id="premain1" style="width: 100%; cursor: pointer; text-align: justify;"&gt;&lt;img preid="1" src="http://www.codeproject.com/images/minus.gif" id="preimg1" width="9" height="9" /&gt;&lt;span preid="1" style="margin-bottom: 0pt;" id="precollapse1"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;pre style="margin-top: 0pt;" id="pre1" lang="text"&gt;&lt;allow-access-from domain="*.yahoo.com"&gt;&lt;/pre&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;(* denotes anything that prepends the domain name e.g. messenger.yahoo.com in also all protocols: HTTP or HTTPS)&lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;h2 style="text-align: justify;"&gt;Vulnerability 3&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;h3 style="text-align: justify;"&gt;Vulnerability Name:  Using SSL v2 in Secure Communications &lt;/h3&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;h4 style="text-align: justify;"&gt;Description&lt;/h4&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;The remote service appears to encrypt traffic using SSL protocol version 2. &lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;Netscape Communications Corporation introduced SSL 2.0 with the launch of Netscape Navigator 1.0 in 1994 and it contains several well-known weaknesses. For example, SSLv2 doesn't provide any protection against man-in-the-middle attacks during the handshake, and uses the same cryptographic keys for message authentication and for encryption. &lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;In Internet Explorer 7, the default HTTPS protocol settings are changed to disable the weaker SSLv2 protocol and to enable the stronger TLSv1 protocol. By default, Internet Explorer 7 users will only negotiate HTTPS connections using SSLv3 or TLSv1. Mozilla Firefox is expected to drop support for SSLv2 in its upcoming versions. &lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;As almost all modern browsers support SSLv3, disabling support for the weaker SSL method should have minimal impact. The following browsers support SSLv3: &lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Internet Explorer 5.5 or higher (PC) &lt;/li&gt;&lt;li&gt;Internet Explorer 5.0 or higher (Mac) &lt;/li&gt;&lt;li&gt;Netscape 2.0 (Domestic) or higher (PC/Mac) &lt;/li&gt;&lt;li&gt;Firefox 0.8 or higher (PC/Mac/Linux) &lt;/li&gt;&lt;li&gt;Mozilla 1.7 or higher (PC/Mac/Linux) &lt;/li&gt;&lt;li&gt;Camino 0.8 or higher (Mac) &lt;/li&gt;&lt;li&gt;Safari 1.0 or higher (Mac) &lt;/li&gt;&lt;li&gt;Opera 1.7 or higher (PC/Mac) &lt;/li&gt;&lt;li&gt;Omniweb 3.0 or higher (Mac) &lt;/li&gt;&lt;li&gt;Konqueror 2.0 or higher (Linux) &lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;According to &lt;em&gt;&lt;a href="https://www.pcisecuritystandards.org/pdfs/pcissc_assessors_nl_2008-11.pdf"&gt;https://www.pcisecuritystandards.org/pdfs/pcissc_assessors_nl_2008-11.pdf&lt;/a&gt;&lt;/em&gt;, an Assessor's update report, "...it is imperative that an ASV identify the use of SSL 2.0 to transmit cardholder data as a failure." &lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;h4 style="text-align: justify;"&gt;Solution&lt;/h4&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;SSL related protocols can run on other service ports as well. Typical ports include: 465, 993, 995, 2078, 2083, 2087, 2096, 8443, etc. Each application will have its own configuration options to handle SSL protocols.&lt;br /&gt;To solve this problem, one needs to open Registry Editor.&lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Click &lt;strong&gt;Start&lt;/strong&gt;, click &lt;strong&gt;Run&lt;/strong&gt;, type regedt32 or type regedit, and then click &lt;strong&gt;OK&lt;/strong&gt;. &lt;/li&gt;&lt;li&gt;In Registry Editor, locate the following registry key:  &lt;div class="SmallText" id="premain2" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="2" src="http://www.codeproject.com/images/minus.gif" id="preimg2" width="9" height="9" /&gt;&lt;span preid="2" style="margin-bottom: 0pt;" id="precollapse2"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre2" lang="text"&gt;HKey_Local_Machine\System\CurrentControlSet\Control\SecurityProviders&lt;br /&gt;    \SCHANNEL\Protocols\SSL 2.0\Server&lt;/pre&gt;  &lt;p&gt;&lt;img alt="Fig3.png" src="http://www.codeproject.com/KB/aspnet/MakeWebsiteMcAfeeSecured/Fig3.png" width="269" height="245" /&gt; &lt;/p&gt; &lt;/li&gt;&lt;li&gt;On the &lt;strong&gt;Edit&lt;/strong&gt; menu, click &lt;strong&gt;Add Value&lt;/strong&gt;. &lt;/li&gt;&lt;li&gt;In the &lt;strong&gt;Data Type&lt;/strong&gt; list, click &lt;strong&gt;DWORD&lt;/strong&gt;.  &lt;p&gt;&lt;img alt="Fig4.png" src="http://www.codeproject.com/KB/aspnet/MakeWebsiteMcAfeeSecured/Fig4.png" width="451" height="284" /&gt;&lt;/p&gt; &lt;/li&gt;&lt;li&gt;In the &lt;strong&gt;Value Name&lt;/strong&gt; box, type &lt;strong&gt;Enabled&lt;/strong&gt;, and then click &lt;strong&gt;OK&lt;/strong&gt;. (The value will be automatically set to 0 – Disabled )  &lt;p&gt;&lt;img alt="Fig5.png" src="http://www.codeproject.com/KB/aspnet/MakeWebsiteMcAfeeSecured/Fig5.png" width="346" height="99" /&gt;&lt;/p&gt; &lt;/li&gt;&lt;li&gt;Next Restart the system and the SSL V2 will be disabled for good.&lt;br /&gt;Reference: &lt;a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;187498"&gt;&lt;em&gt;http://support.microsoft.com/default.aspx?scid=kb;en-us;187498&lt;/em&gt;&lt;/a&gt;. &lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;h2 style="text-align: justify;"&gt;Vulnerability 4&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;h2 style="text-align: justify;"&gt;Vulnerability Name:  Weak Supported SSL Ciphers Suites&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;h4 style="text-align: justify;"&gt;Description&lt;/h4&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;The remote host supports the use of SSL ciphers that offer either weak encryption or no encryption at all. This vulnerability is valid for all SSL/TLS sessions that are passing sensitive information.&lt;br /&gt;PCI defines strong cryptography, for secret key based systems, as anything above 80 bit encryption.&lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;h4 style="text-align: justify;"&gt;Solution&lt;/h4&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;The solution to this is very simple but requires registry tweak again. Following are the steps:&lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Click &lt;strong&gt;Start&lt;/strong&gt;, click &lt;strong&gt;Run&lt;/strong&gt;, type regedt32 or type regedit, and then click &lt;strong&gt;OK&lt;/strong&gt;. &lt;/li&gt;&lt;li&gt;In Registry Editor, locate the following registry key:  &lt;div class="SmallText" id="premain3" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="3" src="http://www.codeproject.com/images/minus.gif" id="preimg3" width="9" height="9" /&gt;&lt;span preid="3" style="margin-bottom: 0pt;" id="precollapse3"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre3" lang="text"&gt;HKey_Local_Machine\System\CurrentControlSet\Control\SecurityProviders&lt;br /&gt;      \SCHANNEL\Ciphers &lt;/pre&gt; &lt;img alt="Fig6.png" src="http://www.codeproject.com/KB/aspnet/MakeWebsiteMcAfeeSecured/Fig6.png" width="270" height="260" /&gt; &lt;/li&gt;&lt;li&gt;Under the Cipher key, there are several Ciphers. &lt;/li&gt;&lt;li&gt;Locate the ciphers which have encryption less than 128 bit. &lt;/li&gt;&lt;li&gt;Create &lt;code&gt;DWORD &lt;/code&gt;values named &lt;code&gt;Enabled &lt;/code&gt;and Value 0 for each of them, just as the previous case. &lt;/li&gt;&lt;li&gt;For convenience, I have marked them with red arrows in the picture above. &lt;/li&gt;&lt;li&gt;System Restart is NOT required for this. &lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;Now the server is secured.&lt;br /&gt;The above mentioned security issues are the major ones that most of the systems have. However other than this, there may be some easy and minor vulnerabilities like:&lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Using &lt;em&gt;robots.txt&lt;/em&gt; in the pages. (Generally inserted by Web Marketing team to track user hit). &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Directory Scanner&lt;/strong&gt;: Common directories are revealed. This can be resolved by URL rewriting and setting “Directory Browsing” off. &lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;em&gt;Note: For the above vulnerabilities, minor registry tweaks will be necessary. So it is strongly recommended to back up the registry before doing anything. By any chance if something gets messed up, just delete the SCHANNEL key and restart the machine, the key will be auto-generated.&lt;/em&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/864116869953733620-7723321109309155792?l=narulaamitsk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://narulaamitsk.blogspot.com/feeds/7723321109309155792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=864116869953733620&amp;postID=7723321109309155792' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/7723321109309155792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/7723321109309155792'/><link rel='alternate' type='text/html' href='http://narulaamitsk.blogspot.com/2009/06/how-to-make-your-website-more-mcafee.html' title='How To Make Your Website More (McAfee) Secure'/><author><name>Amit Narula</name><uri>http://www.blogger.com/profile/03373886236261160868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_KIFo2nRsLTc/SfIq-GgjUkI/AAAAAAAACCo/bBDItRMEB6s/S220/DSCF1775.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-864116869953733620.post-6209059112612659496</id><published>2009-06-13T03:25:00.000-07:00</published><updated>2009-06-13T03:57:19.376-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.Net Perfromance'/><title type='text'>10 ASP.NET Performance and Scalability Secrets</title><content type='html'>&lt;h2&gt;Introduction&lt;/h2&gt;  &lt;p style="text-align: justify;"&gt;ASP.NET 2.0 has many secrets, which when revealed can give you big performance and scalability boost. For instance, there are secret bottlenecks in Membership and Profile provider which can be solved easily to make authentication and authorization faster. Furthermore, ASP.NET HTTP pipeline can be tweaked to avoid executing unnecessary code that gets hit on each and every request. Not only that, ASP.NET Worker Process can be pushed to its limit to squeeze out every drop of performance out of it. Page fragment output caching on the browser (not on the server) can save significant amount of download time on repeated visits. On demand UI loading can give your site a fast and smooth feeling. Finally, Content Delivery Networks (CDN) and proper use of HTTP Cache headers can make your website screaming fast when implemented properly. In this article, you will learn these techniques that can give your ASP.NET application a big performance and scalability boost and prepare it to perform well under 10 times to 100 times more traffic. &lt;/p&gt;  &lt;p&gt;In this article we will discuss the following techniques:&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;ASP.NET pipeline optimization &lt;/li&gt;&lt;li&gt;ASP.NET process configuration optimization &lt;/li&gt;&lt;li&gt;Things you must do for ASP.NET before going live &lt;/li&gt;&lt;li&gt;Content Delivery Network &lt;/li&gt;&lt;li&gt;Caching AJAX calls on browser &lt;/li&gt;&lt;li&gt;Making best use of Browser Cache &lt;/li&gt;&lt;li&gt;On demand progressive UI loading for fast smooth experience &lt;/li&gt;&lt;li&gt;Optimize ASP.NET 2.0 Profile provider &lt;/li&gt;&lt;li&gt;How to query ASP.NET 2.0 Membership tables without bringing down the site &lt;/li&gt;&lt;li&gt;Prevent Denial of Service (DOS) attack &lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;The above techniques can be implemented on any ASP.NET website, especially those who use ASP.NET 2.0's Membership and Profile provider.&lt;/p&gt;  &lt;p&gt;&lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;ASP.NET Pipeline Optimization&lt;/h2&gt;  &lt;p style="text-align: justify;"&gt;There are several ASP.NET default &lt;code style="color: rgb(255, 0, 0);"&gt;HttpModules&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;which sit in the request pipeline and intercept each and every request. For example, &lt;code style="color: rgb(255, 0, 0);"&gt;SessionStateModule&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;intercepts each request, parses the session cookie and then loads the proper session in the &lt;code style="color: rgb(255, 0, 0);"&gt;HttpContext&lt;/code&gt;. Not all of these modules are always necessary. For example, if you aren't using Membership and Profile provider, you don't need &lt;code style="color: rgb(255, 0, 0);"&gt;FormsAuthentication&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;module. If you aren't using Windows Authentication for your users, you don't need &lt;code style="color: rgb(255, 0, 0);"&gt;WindowsAuthentication&lt;/code&gt;. These modules are just sitting in the pipeline, executing some unnecessary code for each and every request. &lt;/p&gt;  &lt;p&gt;The default modules are defined in &lt;em&gt;machine.config&lt;/em&gt; file (located in the &lt;em&gt;$WINDOWS$\Microsoft.NET\Framework\$VERSION$\CONFIG&lt;/em&gt; directory). &lt;/p&gt;  &lt;div class="SmallText" id="premain0" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="0" src="http://www.codeproject.com/images/minus.gif" id="preimg0" width="9" height="9" /&gt;&lt;span preid="0" style="margin-bottom: 0pt;" id="precollapse0"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt; color: rgb(255, 0, 0);" id="pre0" lang="xml"&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;httpModules&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;add&lt;/span&gt; &lt;span class="code-attribute"&gt;name&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;OutputCache"&lt;/span&gt; &lt;span class="code-attribute"&gt;type&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;System.Web.Caching.OutputCacheModule"&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;add&lt;/span&gt; &lt;span class="code-attribute"&gt;name&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;Session"&lt;/span&gt; &lt;span class="code-attribute"&gt;type&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;System.Web.SessionState.SessionStateModule"&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;add&lt;/span&gt; &lt;span class="code-attribute"&gt;name&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;WindowsAuthentication"&lt;/span&gt;&lt;br /&gt;     &lt;span class="code-attribute"&gt;type&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;System.Web.Security.WindowsAuthenticationModule"&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;add&lt;/span&gt; &lt;span class="code-attribute"&gt;name&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;FormsAuthentication"&lt;/span&gt;&lt;br /&gt;     &lt;span class="code-attribute"&gt;type&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;System.Web.Security.FormsAuthenticationModule"&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;add&lt;/span&gt; &lt;span class="code-attribute"&gt;name&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;PassportAuthentication"&lt;/span&gt;&lt;br /&gt;     &lt;span class="code-attribute"&gt;type&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;System.Web.Security.PassportAuthenticationModule"&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;add&lt;/span&gt; &lt;span class="code-attribute"&gt;name&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;UrlAuthorization"&lt;/span&gt; &lt;span class="code-attribute"&gt;type&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;System.Web.Security.UrlAuthorizationModule"&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;add&lt;/span&gt; &lt;span class="code-attribute"&gt;name&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;FileAuthorization"&lt;/span&gt; &lt;span class="code-attribute"&gt;type&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;System.Web.Security.FileAuthorizationModule"&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;add&lt;/span&gt; &lt;span class="code-attribute"&gt;name&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;ErrorHandlerModule"&lt;/span&gt; &lt;span class="code-attribute"&gt;type&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;System.Web.Mobile.ErrorHandlerModule,&lt;br /&gt;                          System.Web.Mobile, Version=1.0.5000.0,&lt;br /&gt;                          Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-leadattribute"&gt;httpModules&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;/pre&gt;  &lt;p&gt;You can remove these default modules from your Web application by adding &lt;code style="color: rgb(255, 0, 0);"&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;remove&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;/code&gt; nodes in your site's &lt;em&gt;web.config&lt;/em&gt;. For example: &lt;/p&gt;  &lt;div class="SmallText" id="premain1" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="1" src="http://www.codeproject.com/images/minus.gif" id="preimg1" width="9" height="9" /&gt;&lt;span preid="1" style="margin-bottom: 0pt;" id="precollapse1"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: justify; color: rgb(255, 0, 0);"&gt;&lt;pre style="margin-top: 0pt;" id="pre1" lang="xml"&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;httpModules&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="code-comment"&gt;&lt;!--&lt;/span&gt;&lt;span class="code-keyword"&gt;&lt;span class="code-comment"&gt; Remove unnecessary Http Modules for faster pipeline &lt;/span&gt;--&gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;remove&lt;/span&gt; &lt;span class="code-attribute"&gt;name&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;Session"&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;remove&lt;/span&gt; &lt;span class="code-attribute"&gt;name&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;WindowsAuthentication"&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;remove&lt;/span&gt; &lt;span class="code-attribute"&gt;name&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;PassportAuthentication"&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;remove&lt;/span&gt; &lt;span class="code-attribute"&gt;name&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;AnonymousIdentification"&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;remove&lt;/span&gt; &lt;span class="code-attribute"&gt;name&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;UrlAuthorization"&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;      &lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;remove&lt;/span&gt; &lt;span class="code-attribute"&gt;name&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;FileAuthorization"&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-leadattribute"&gt;httpModules&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;p&gt;The above configuration is suitable for websites that use database based Forms Authentication and do not need any Session support. So, all these modules can safely be removed. &lt;/p&gt;  &lt;h2&gt;ASP.NET Process Configuration Optimization &lt;/h2&gt;  &lt;p style="text-align: justify;"&gt;ASP.NET Process Model configuration defines some process level properties like how many number of threads ASP.NET uses, how long it blocks a thread before timing out, how many requests to keep waiting for IO works to complete and so on. The default is in many cases too limiting. Nowadays hardware has become quite cheap and dual core with gigabyte RAM servers have become a very common choice. So, the process model configuration can be tweaked to make ASP.NET process consume more system resources and provide better scalability from each server. &lt;/p&gt;  &lt;p&gt;A regular ASP.NET installation will create &lt;em&gt;machine.config&lt;/em&gt; with the following configuration: &lt;/p&gt;  &lt;div class="SmallText" id="premain2" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="2" src="http://www.codeproject.com/images/minus.gif" id="preimg2" width="9" height="9" /&gt;&lt;span preid="2" style="margin-bottom: 0pt;" id="precollapse2"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre2" lang="xml"&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-leadattribute"&gt;system.web&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-leadattribute"&gt;processModel&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-attribute"&gt;autoConfig&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-keyword"&gt;="&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-keyword"&gt;true"&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-keyword"&gt;/&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt; &lt;/pre&gt;  &lt;p&gt;You need to tweak this auto configuration and use some specific values for different attributes in order to customize the way ASP.NET worker process works. For example:&lt;/p&gt;  &lt;div class="SmallText" id="premain3" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="3" src="http://www.codeproject.com/images/minus.gif" id="preimg3" width="9" height="9" /&gt;&lt;span preid="3" style="margin-bottom: 0pt;" id="precollapse3"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt; color: rgb(255, 0, 0);" id="pre3" lang="xml"&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;processModel&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;enable&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;true"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;timeout&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;Infinite"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;idleTimeout&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;Infinite"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;shutdownTimeout&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;00:00:05"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;requestLimit&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;Infinite"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;requestQueueLimit&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;5000"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;restartQueueLimit&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;10"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;memoryLimit&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;60"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;webGarden&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;false"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;cpuMask&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;0xffffffff"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;userName&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;machine"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;password&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;AutoGenerate"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;logLevel&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;Errors"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;clientConnectedCheck&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;00:00:05"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;comAuthenticationLevel&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;Connect"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;comImpersonationLevel&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;Impersonate"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;responseDeadlockInterval&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;00:03:00"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;responseRestartDeadlockInterval&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;00:03:00"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;autoConfig&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;false"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;maxWorkerThreads&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;100"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;maxIoThreads&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;100"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;minWorkerThreads&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;40"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;minIoThreads&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;30"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;serverErrorMessageFile&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;pingFrequency&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;Infinite"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;pingTimeout&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;Infinite"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;asyncOption&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;20"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;maxAppDomains&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;2000"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;/pre&gt;  &lt;p&gt;Here all the values are default values except for the following ones:&lt;/p&gt;  &lt;ul&gt;&lt;li style="text-align: justify;"&gt;&lt;code style="color: rgb(255, 0, 0);"&gt;maxWorkerThreads&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;- This is default to 20 per process. On a dual core computer, there'll be 40 threads allocated for ASP.NET. This means at a time ASP.NET can process 40 requests in parallel on a dual core server. I have increased it to 100 in order to give ASP.NET more threads per process. If you have an application which is not that CPU intensive and can easily take in more requests per second, then you can increase this value. Especially if your Web application uses a lot of Web service calls or downloads/uploads a lot of data which does not put pressure on the CPU. When ASP.NET runs out of worker threads, it stops processing more requests that come in. Requests get into a queue and keeps waiting until a worker thread is freed. This generally happens when site starts receiving much more hits than you originally planned. In that case, if you have CPU to spare, increase the worker threads count per process. &lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;code style="color: rgb(255, 0, 0);"&gt;maxIOThreads&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;- This is default to 20 per process. On a dual core computer, there'll be 40 threads allocated for ASP.NET for I/O operations. This means at a time ASP.NET can process 40 I/O requests in parallel on a dual core server. I/O requests can be file read/write, database operations, web service calls, HTTP requests generated from within the Web application and so on. So, you can set this to 100 if your server has enough system resource to do more of these I/O requests. Especially when your Web application downloads/uploads data, calls many external webservices in parallel. &lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;code style="color: rgb(255, 0, 0);"&gt;minWorkerThreads&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;- When a number of free ASP.NET worker threads fall below this number, ASP.NET starts putting incoming requests into a queue. So, you can set this value to a low number in order to increase the number of concurrent requests. However, do not set this to a very low number because Web application code might need to do some background processing and parallel processing for which it will need some free worker threads. &lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;code style="color: rgb(255, 0, 0);"&gt;minIOThreads&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;- Same as &lt;code style="color: rgb(255, 0, 0);"&gt;minWorkerThreads&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;but this is for the I/O threads. However, you can set this to a lower value than &lt;code style="color: rgb(255, 0, 0);"&gt;minWorkerThreads&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;because there's no issue of parallel processing in case of I/O threads. &lt;/li&gt;&lt;li style="text-align: justify;"&gt;&lt;code style="color: rgb(255, 0, 0);"&gt;memoryLimit&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;- Specifies the maximum allowed memory size, as a percentage of total system memory, that the worker process can consume before ASP.NET launches a new process and reassigns existing requests. If you have only your Web application running in a dedicated box and there's no other process that needs RAM, you can set a high value like 80. However, if you have a leaky application that continuously leaks memory, then it's better to set it to a lower value so that the leaky process is recycled pretty soon before it becomes a memory hog and thus keep your site healthy. Especially when you are using COM components and leaking memory. However, this is a temporary solution, you of course need to fix the leak.&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;Besides the &lt;code style="color: rgb(255, 0, 0);"&gt;processModel&lt;/code&gt;, there's another very important section with the &lt;code&gt;system.net &lt;/code&gt;where you can specify the maximum number of outbound requests that can be made to a single IP. &lt;/p&gt;  &lt;div class="SmallText" id="premain4" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="4" src="http://www.codeproject.com/images/minus.gif" id="preimg4" width="9" height="9" /&gt;&lt;span preid="4" style="margin-bottom: 0pt;" id="precollapse4"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt; color: rgb(255, 0, 0);" id="pre4" lang="xml"&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;system.net&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;connectionManagement&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;add&lt;/span&gt; &lt;span class="code-attribute"&gt;address&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;*"&lt;/span&gt; &lt;span class="code-attribute"&gt;maxconnection&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;100"&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-leadattribute"&gt;connectionManagement&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-leadattribute"&gt;system.net&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;/pre&gt;  &lt;p style="text-align: justify;"&gt;Default is 2, which is just too low. This means you cannot make more than 2 simultaneous connections to an IP from your Web application. Sites that fetch external content a lot suffer from congestion due to the default setting. Here I have set it to &lt;code&gt;&lt;span class="code-digit"&gt;100&lt;/span&gt;&lt;/code&gt;. If your Web applications make a lot of calls to a specific server, you can consider setting an even higher value.&lt;/p&gt;  &lt;p&gt;You can learn more about these configuration settings from "&lt;a href="http://msdn2.microsoft.com/en-us/library/ms998549.aspx" mce_href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/scalenetchapt06.asp"&gt;Improving ASP.NET Performance&lt;/a&gt;".&lt;/p&gt;  &lt;h2&gt;Things You Must Do for ASP.NET Before Going Live &lt;/h2&gt;  &lt;p&gt;You should do some tweaking on your &lt;em&gt;web.config&lt;/em&gt; if you are using ASP.NET 2.0 Membership Provider before you go live on your production server: &lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;div style="text-align: justify;"&gt;Add &lt;code style="color: rgb(255, 0, 0);"&gt;applicationname&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;attribute in Profile Provider. If you do not add a specific name here, Profile provider will use a &lt;code style="color: rgb(255, 0, 0);"&gt;GUID&lt;/code&gt;. So, on your local machine you will have one &lt;code style="color: rgb(255, 0, 0);"&gt;GUID &lt;/code&gt;and on the production server you will have another &lt;code style="color: rgb(255, 0, 0);"&gt;GUID&lt;/code&gt;. If you copy your local DB to the production server, you won't be able to reuse the records available in your local DB and ASP.NET will create a new application on production. Here's where you need to add it:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="SmallText" id="premain5" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="5" src="http://www.codeproject.com/images/minus.gif" id="preimg5" width="9" height="9" /&gt;&lt;span preid="5" style="margin-bottom: 0pt;" id="precollapse5"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt; color: rgb(255, 0, 0);" id="pre5" lang="xml"&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;profile&lt;/span&gt; &lt;span class="code-attribute"&gt;enabled&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;true"&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;providers&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;clear&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;add&lt;/span&gt; &lt;span class="code-attribute"&gt;name&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;..."&lt;/span&gt; &lt;span class="code-attribute"&gt;type&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;System.Web.Profile.SqlProfileProvider"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;connectionStringName&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;..."&lt;/span&gt; &lt;span class="code-attribute"&gt;applicationName&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;YourApplicationName"&lt;/span&gt;&lt;br /&gt;&lt;span class="code-attribute"&gt;description&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;..."&lt;/span&gt; &lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-leadattribute"&gt;providers&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt; &lt;/pre&gt; &lt;/li&gt;&lt;li&gt;Profile provider will automatically save the profile whenever a page request completes. So, this might result in an unnecessary UPDATE on your DB which has significant performance penalty. So, turn off automatic save and do it explicitly from your code using &lt;code style="color: rgb(255, 0, 0);"&gt;Profile.Save();&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="SmallText" id="premain6" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="6" src="http://www.codeproject.com/images/minus.gif" id="preimg6" width="9" height="9" /&gt;&lt;span preid="6" style="margin-bottom: 0pt;" id="precollapse6"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt; color: rgb(255, 0, 0);" id="pre6" lang="xml"&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;profile&lt;/span&gt; &lt;span class="code-attribute"&gt;enabled&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;true"&lt;/span&gt; &lt;span class="code-attribute"&gt;automaticSaveEnabled&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;false"&lt;/span&gt; &lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;/pre&gt; &lt;/li&gt;&lt;li&gt;&lt;div style="text-align: justify;"&gt;Role Manager always queries the database in order to get the user roles. This has significant performance penalty. You can avoid this by letting the Role Manager cache role information on a cookie. But this will work for users who do not have a lot of roles assigned to them which exceeds the 2 KB limit of Cookie. But it's not a common scenario. So, you can safely store role info on a cookie and save one DB roundtrip on every request to &lt;em&gt;*.aspx&lt;/em&gt; and &lt;em&gt;*.asmx&lt;/em&gt;.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="SmallText" id="premain7" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="7" src="http://www.codeproject.com/images/minus.gif" id="preimg7" width="9" height="9" /&gt;&lt;span preid="7" style="margin-bottom: 0pt;" id="precollapse7"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt; color: rgb(255, 0, 0);" id="pre7" lang="xml"&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;roleManager&lt;/span&gt; &lt;span class="code-attribute"&gt;enabled&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;true"&lt;/span&gt; &lt;span class="code-attribute"&gt;cacheRolesInCookie&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;true"&lt;/span&gt; &lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;/pre&gt; &lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;The above three settings are must haves for high volume websites. &lt;/p&gt;  &lt;h2&gt;Content Delivery Network &lt;/h2&gt;  &lt;p style="text-align: justify;"&gt;Every request from a browser goes to your server traveling through the Internet backbones that span the world. The number of countries, continents, oceans a request has to go through to reach your server, the slower it is. For example, if you have your servers in USA and someone from Australia is browsing your site, each request is literary crossing the planet from one end to the other in order to reach your server and then come back again to the browser. If your site has large number of static files like images, CSS, JavaScript; sending request for each of them and downloading them across the world takes a significant amount of time. If you could setup a server in Australia and redirect users to your Australian server, then each request would take fraction of the time it takes to reach USA. Not only the network latency will be lower but also the data transfer rate will be faster and thus static content will download a lot faster. This will give significant performance improvement on the user�s end if your website is rich in static content. Moreover, ISPs provide far greater speed for country wide network compared to the Internet because each country generally has handful of connectivity to the Internet backbone that is shared by all ISPs within the country. As a result, users having 4 MBPS broadband connection will get the full 4 MBPS speed from servers that are within the same country. But they will get as low as 512 KBPS from servers which are outside the country. Thus having a server in the same country significantly improves site download speed and responsiveness. &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;Besides improving site load speed, CDN also offloads traffic from your Web servers. As it deals with static cacheable content, your webservers rarely get hits for those content. Thus hits going to your webservers drop significantly and webservers free up more resource to process dynamic requests. Your webservers also save a lot of IIS log space because IIS need not log requests for the static contents. If you have a lot of graphics, CSS and JavaScript on your website, you can save gigabytes of IIS logs every day. &lt;/p&gt; &lt;img alt="clip_image002[4]" src="http://www.codeproject.com/KB/aspnet/10ASPNetPerformance/clip_image0024.gif" mce_src="http://omar.mvps.org/images/MakeyourwebsitefasterusingContentDeliver_13C7F/clip_image0024.gif" width="480" border="0" height="266" hspace="0" /&gt;  &lt;p style="text-align: justify;"&gt;Above figure shows average response time for &lt;a href="http://www.pageflakes.com/" mce_href="http://www.pageflakes.com/"&gt;www.pageflakes.com&lt;/a&gt; from Washington, DC, where the servers are in Dallas, Texas. The average response time is around 0.4 seconds. This response includes server side execution time as well. Generally it takes around 0.3 to 0.35 seconds to execute the page on the server. So, time spent on the network is around 0.05 seconds or 50ms. This is a really fast connectivity as there are only 4 to 6 hops to reach Dallas from Washington DC. &lt;/p&gt; &lt;img alt="clip_image004[4]" src="http://www.codeproject.com/KB/aspnet/10ASPNetPerformance/clip_image0044.gif" mce_src="http://omar.mvps.org/images/MakeyourwebsitefasterusingContentDeliver_13C7F/clip_image0044.gif" width="480" border="0" height="262" hspace="0" /&gt;  &lt;p style="text-align: justify;"&gt;&lt;a&gt;This&lt;/a&gt; figure shows average response time from Sydney, Australia. The average response time is 1.5 seconds which is significantly higher than that of Washington DC. It�s almost 4 times compared to USA. There's almost 1.2 seconds overhead on network only. Moreover, there are around 17 to 23 hops from Sydney to Dallas. So, the site downloads at least 4 times slower in Australia than it is from anywhere in USA. &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;A content delivery network (CDN) is a system of computers networked together across the Internet. The computers cooperate transparently to deliver content (especially large media content) to end users. CDN nodes (cluster of servers in a specific location) are deployed in multiple locations, often over multiple backbones. These nodes cooperate with each other to serve requests for content by end users. They also transparently move content behind the scenes to optimize the delivery process. CDN serves requests by intelligently choosing the nearest server. It looks for the fastest connectivity between your computer to a nearest node that has the content you are looking for. The number of nodes in different countries and the number of redundant backbone connectivity a CDN has measures its strength. Some of the most popular CDNs are Akamai, Limelight, EdgeCast. Akamai is used by large companies like Microsoft, Yahoo, AOL. It�s a comparatively expensive solution. However, Akamai has the best performance throughout the world because they have servers in almost every prominent city in the world. However, Akamai is very expensive and they only accept a customer who can spend a minimum of 5K on CDN per month. For smaller companies, Edgecast is a more affordable solution. &lt;/p&gt; &lt;img alt="clip_image006[4]" src="http://www.codeproject.com/KB/aspnet/10ASPNetPerformance/clip_image0064.jpg" mce_src="http://omar.mvps.org/images/MakeyourwebsitefasterusingContentDeliver_13C7F/clip_image0064.jpg" width="480" border="0" height="333" hspace="0" /&gt;  &lt;p style="text-align: justify;"&gt;This figure shows CDN Nodes that are closest to the browser intercepts traffic and serves response. If it does not have the response in cache, it fetches it from origin server using a faster route and much more optimized connectivity than the browser�s ISP can provide. If the content is already cached, then it�s served directly from the node and no request goes to the origin server. &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;There are generally two types of CDNs. One is where you upload content to CDN's servers via FTP and you get a subdomain in their domain like &lt;em&gt;dropthings.somecdn.net&lt;/em&gt;. You change all the URL of static content throughout your site to download content from the CDN domain instead of the relative URL to your own domain. So, a URL like &lt;em&gt;/logo.gif&lt;/em&gt; will be renamed to &lt;em&gt;http://dropthings.somecdn.net/logo.gif&lt;/em&gt;. This is easy to configure but has maintenance problems. You will have to keep CDN�s store synchronized with the files all the time. Deployment becomes complicated because you need to update both your website and the CDN store at the same time. Example of such a CDN (which is very cheap) is &lt;a href="http://www.cachefly.com/" mce_href="http://www.cachefly.com"&gt;Cachefly&lt;/a&gt;. &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;A more convenient approach is to store static content on your own site but use domain aliasing. You can store your content in a subdomain that points to your own domain like &lt;em&gt;static.dropthings.com&lt;/em&gt;. Then you use CNAME to map that subdomain to a CDN�s nameserver like &lt;em&gt;cache.somecdn.&lt;/em&gt;&lt;a&gt;&lt;em&gt;net&lt;/em&gt;&lt;/a&gt;. When a browser tries to resolve &lt;em&gt;static.dropthigns.com&lt;/em&gt;, the DNS lookup request goes to the CDN nameserver. The nameserver then returns IP of a CDN node which is closest to you and can give you the best download performance. The browser then sends requests for files to that CDN node. When CDN node sees the request, it checks whether it has the content already cached. If it is cached, it delivers the content directly from its local store. If not, it makes a request to your server and then looks at the cache header generated in response. Based on the cache header it decides how long to cache the response in its own cache. In the meantime, the browser does not wait for CDN node to get content and return to it. CDN does an interesting trick on the Internet backbone to actually route requests to the origin server so that the browser gets the response directly served from origin server while CDN is updating its &lt;a&gt;cache&lt;/a&gt;. Sometimes CDN act as a proxy, intercepting each request and then fetching uncached content from the origin using a faster route and optimized connectivity to the origin server. Example of such CDN is &lt;a href="http://edgecast.com/" mce_href="http://edgecast.com/"&gt;Edgecast&lt;/a&gt;. &lt;/p&gt;  &lt;h2&gt;Caching AJAX Calls on Browser &lt;/h2&gt;  &lt;p style="text-align: justify;"&gt;Browsers can cache images, JavaScript, CSS files on a user's hard drive, and it can also cache XML HTTP calls if the call is a HTTP &lt;code style="color: rgb(255, 0, 0);"&gt;GET&lt;/code&gt;. The cache is based on the URL. If it's the same URL, and it's cached on the computer, then the response is loaded from the cache, not from the server when it is requested again. Basically, the browser can cache any HTTP &lt;code style="color: rgb(255, 0, 0);"&gt;GET &lt;/code&gt;call and return cached data based on the URL. If you make an XML HTTP call as HTTP &lt;code style="color: rgb(255, 0, 0);"&gt;GET &lt;/code&gt;and the server returns some special header which informs the browser to cache the response, on future calls, the response will be immediately returned from the cache and thus saves the delay of network roundtrip and download time. &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;At Pageflakes, we cache the user's state so that when the user visits again the following day, the user gets a cached page which loads instantly from the browser cache, not from the server. Thus the second time load becomes very fast. We also cache several small parts of the page which appears on user's actions. When the user performs the same action again, a cached result is loaded immediately from the local cache and thus saves the network roundtrip time. The user gets a fast loading site and a very responsive site. The perceived speed increases dramatically. &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;The idea is to make HTTP &lt;code style="color: rgb(255, 0, 0);"&gt;GET &lt;/code&gt;calls while making Atlas Web service calls and return some specific HTTP Response headers that tell the browser to cache the response for some specific duration. If you return the &lt;code style="color: rgb(255, 0, 0);"&gt;Expires&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;header during the response, the browser will cache the XML HTTP response. There are two headers that you need to return with the response that instruct the browser to cache the response:&lt;/p&gt;  &lt;div class="SmallText" id="premain8" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="8" src="http://www.codeproject.com/images/minus.gif" id="preimg8" width="9" height="9" /&gt;&lt;span preid="8" style="margin-bottom: 0pt;" id="precollapse8"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt; color: rgb(255, 0, 0);" id="pre8" lang="text"&gt;HTTP/1.1 200 OK&lt;br /&gt;Expires: Fri, 1 Jan 2030&lt;br /&gt;Cache-Control: public&lt;/pre&gt;  &lt;p style="text-align: justify;"&gt;This instructs the browser to cache the response till Jan 2030. As long as you make the same XML HTTP call with the same parameters, you will get cached response from the computer and no call will go to the origin server. There are more advanced ways to get further control over response caching. For example, here is a header that instructs the browser to cache for 60 seconds but contact the server and get a fresh response after 60 seconds. It will also prevent proxies from returning cached response when the browser local cache expires after 60 seconds.&lt;/p&gt;  &lt;div class="SmallText" id="premain9" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="9" src="http://www.codeproject.com/images/minus.gif" id="preimg9" width="9" height="9" /&gt;&lt;span preid="9" style="margin-bottom: 0pt;" id="precollapse9"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt; color: rgb(255, 0, 0);" id="pre9" lang="text"&gt;HTTP/1.1 200 OK&lt;br /&gt;Cache-Control: private, must-revalidate, proxy-revalidate, max-age=60&lt;/pre&gt;  &lt;p&gt;Let's try to produce such response headers from an ASP.NET Web service call:&lt;/p&gt;  &lt;div class="SmallText" id="premain10" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="10" src="http://www.codeproject.com/images/minus.gif" id="preimg10" width="9" height="9" /&gt;&lt;span preid="10" style="margin-bottom: 0pt;" id="precollapse10"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt; color: rgb(255, 0, 0);" id="pre10" lang="cs"&gt;[WebMethod][ScriptMethod(UseHttpGet=true)]&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-keyword"&gt;public&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);" class="code-keyword"&gt;string&lt;/span&gt; CachedGet()&lt;br /&gt;{&lt;br /&gt; TimeSpan cacheDuration = TimeSpan.FromMinutes(&lt;span style="color: rgb(255, 0, 0);" class="code-digit"&gt;1&lt;/span&gt;);&lt;br /&gt; Context.Response.Cache.SetCacheability(HttpCacheability.Public);&lt;br /&gt; Context.Response.Cache.SetExpires(DateTime.Now.Add(cacheDuration));&lt;br /&gt; Context.Response.Cache.SetMaxAge(cacheDuration);&lt;br /&gt; Context.Response.Cache.AppendCacheExtension(&lt;br /&gt;        &lt;span style="color: rgb(255, 0, 0);" class="code-string"&gt;"&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-string"&gt;must-revalidate, proxy-revalidate"&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt; &lt;span style="color: rgb(255, 0, 0);" class="code-keyword"&gt;return&lt;/span&gt; DateTime.Now.ToString();&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;This will result in the following response headers: &lt;/p&gt; &lt;img src="http://www.codeproject.com/KB/aspnet/10ASPNetPerformance/cacheheader.png" mce_src="http://www.codeproject.com/KB/ajax/aspnetajaxtips/cacheheader.png" width="427" border="0" height="125" hspace="0" /&gt;  &lt;p style="text-align: justify;"&gt;The &lt;code style="color: rgb(255, 0, 0);"&gt;Expires&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;header is set properly. But the problem is with the &lt;code style="color: rgb(255, 0, 0);"&gt;Cache-control&lt;/code&gt;. It is showing that &lt;code style="color: rgb(255, 0, 0);"&gt;max-age&lt;/code&gt; is set to &lt;code style="color: rgb(255, 0, 0);"&gt;&lt;span class="code-digit"&gt;0&lt;/span&gt;&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;which will prevent the browser from doing any kind of caching. If you seriously want to prevent caching, you should emit such a cache-control header. Looks like exactly the opposite thing happened. &lt;/p&gt;  &lt;p&gt;The output is as usual incorrect, and not cached: &lt;/p&gt; &lt;img src="http://www.codeproject.com/KB/aspnet/10ASPNetPerformance/noncachedoutput.gif" mce_src="http://www.codeproject.com/KB/ajax/aspnetajaxtips/noncachedoutput.gif" width="344" border="0" height="169" hspace="0" /&gt;  &lt;p style="text-align: justify;"&gt;There's a bug in ASP.NET 2.0 that you cannot change the &lt;code style="color: rgb(255, 0, 0);"&gt;max-age&lt;/code&gt; header. As &lt;code style="color: rgb(255, 0, 0);"&gt;max-age&lt;/code&gt; is set to &lt;code style="color: rgb(255, 0, 0);"&gt;&lt;span class="code-digit"&gt;0&lt;/span&gt;&lt;/code&gt;, ASP.NET 2.0 sets the &lt;code style="color: rgb(255, 0, 0);"&gt;Cache-control&lt;/code&gt; to private because &lt;code style="color: rgb(255, 0, 0);"&gt;max-age = &lt;span class="code-digit"&gt;0&lt;/span&gt; &lt;/code&gt;means no cache is needed. So, there's no way you can make ASP.NET 2.0 return proper headers which cache the response. This is due to the ASP.NET AJAX Framework that intercepts calls to Webservices and incorrectly sets the &lt;code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;max-ag&lt;/span&gt;e &lt;/code&gt;to &lt;code style="color: rgb(255, 0, 0);"&gt;&lt;span class="code-digit"&gt;0&lt;/span&gt;&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;by default before executing a request. &lt;/p&gt;  &lt;p&gt;Time for a hack. After decompiling the code of the &lt;code style="color: rgb(255, 0, 0);"&gt;HttpCachePolicy&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;class (&lt;code style="color: rgb(255, 0, 0);"&gt;Context.Response.Cache&lt;/code&gt; object's class), I found the following code: &lt;/p&gt; &lt;img src="http://www.codeproject.com/KB/aspnet/10ASPNetPerformance/SetMaxAge.png" mce_src="http://www.codeproject.com/KB/ajax/aspnetajaxtips/SetMaxAge.png" width="441" border="0" height="260" hspace="0" /&gt;  &lt;p style="text-align: justify;"&gt;Somehow, &lt;code style="color: rgb(255, 0, 0);"&gt;&lt;span class="code-keyword"&gt;this&lt;/span&gt;._maxAge&lt;/code&gt; is getting set to &lt;code&gt;&lt;span class="code-digit"&gt;0&lt;/span&gt;&lt;/code&gt; and the check: "&lt;code style="color: rgb(255, 0, 0);"&gt;&lt;span class="code-keyword"&gt;if&lt;/span&gt; (!this._isMaxAgeSet || (delta &lt;span class="code-keyword"&gt;&lt;&lt;/span&gt; &lt;span class="code-keyword"&gt;this&lt;/span&gt;._maxAge))&lt;/code&gt;" is preventing it from getting set to a bigger value. Due to this problem, we need to bypass the &lt;code style="color: rgb(255, 0, 0);"&gt;SetMaxAge&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;function and set the value of the &lt;code style="color: rgb(255, 0, 0);"&gt;_maxAge&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;field directly, using Reflection.&lt;/p&gt;  &lt;div class="SmallText" id="premain11" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="11" src="http://www.codeproject.com/images/minus.gif" id="preimg11" width="9" height="9" /&gt;&lt;span preid="11" style="margin-bottom: 0pt;" id="precollapse11"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre11" lang="cs"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;[WebMethod][ScriptMethod(UseHttpGet=true)]&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-keyword"&gt;public&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-keyword"&gt;string&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; CachedGet2()&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;  TimeSpan cacheDuration = TimeSpan.FromMinutes(&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-digit"&gt;1&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;  FieldInfo maxAge = Context.Response.Cache.GetType().GetField(&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-string"&gt;"&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-string"&gt;_maxAge"&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;      BindingFlags.Instance|BindingFlags.NonPublic);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;  maxAge.SetValue(Context.Response.Cache, cacheDuration);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;  Context.Response.Cache.SetCacheability(HttpCacheability.Public);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;  Context.Response.Cache.SetExpires(DateTime.Now.Add(cacheDuration));&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;  Context.Response.Cache.AppendCacheExtension(&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;          &lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-string"&gt;"&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-string"&gt;must-revalidate, proxy-revalidate"&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;  &lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);" class="code-keyword"&gt;return&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; DateTime.Now.ToString();&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;This will return the following headers: &lt;/p&gt; &lt;img src="http://www.codeproject.com/KB/aspnet/10ASPNetPerformance/cacheheader2.png" mce_src="http://www.codeproject.com/KB/ajax/aspnetajaxtips/cacheheader2.png" width="439" border="0" height="125" hspace="0" /&gt;  &lt;p style="text-align: justify;"&gt;Now &lt;code&gt;max-age &lt;/code&gt;is set to &lt;code&gt;&lt;span class="code-digit"&gt;60&lt;/span&gt;&lt;/code&gt; and thus the browser will cache the response for 60 seconds. If you make the same call again within 60 seconds, it will return the same response. Here's a test output which shows the date time returned from the server: &lt;/p&gt; &lt;img src="http://www.codeproject.com/KB/aspnet/10ASPNetPerformance/cacheworks.gif" mce_src="http://www.codeproject.com/KB/ajax/aspnetajaxtips/cacheworks.gif" width="346" border="0" height="168" hspace="0" /&gt;  &lt;p style="text-align: justify;"&gt;After 1 minute, the cache expires and the browser makes a call to the server again. The client side code is like this:&lt;/p&gt;  &lt;div class="SmallText" id="premain12" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="12" src="http://www.codeproject.com/images/minus.gif" id="preimg12" width="9" height="9" /&gt;&lt;span preid="12" style="margin-bottom: 0pt;" id="precollapse12"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt; color: rgb(255, 0, 0);" id="pre12" lang="cs"&gt;function testCache()&lt;br /&gt;{&lt;br /&gt; TestService.CachedGet(function(result)&lt;br /&gt; {&lt;br /&gt;     debug.trace(result);&lt;br /&gt; });&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;There's another problem to solve. In &lt;em&gt;web.config&lt;/em&gt;, you will see ASP.NET Ajax will add:&lt;/p&gt;  &lt;div class="SmallText" id="premain13" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="13" src="http://www.codeproject.com/images/minus.gif" id="preimg13" width="9" height="9" /&gt;&lt;span preid="13" style="margin-bottom: 0pt;" id="precollapse13"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt; color: rgb(255, 0, 0);" id="pre13" lang="xml"&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;system.web&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;trust&lt;/span&gt; &lt;span class="code-attribute"&gt;level&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;Medium"&lt;/span&gt;&lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;/pre&gt;  &lt;p&gt;This prevents us from setting &lt;code style="color: rgb(255, 0, 0);"&gt;_maxAge&lt;/code&gt;&lt;span style="color: rgb(255, 0, 0);"&gt; &lt;/span&gt;field of &lt;code&gt;Response&lt;/code&gt; object because it requires Reflection. So, you will have to remove this trust level or put &lt;code&gt;Full&lt;/code&gt;.&lt;/p&gt;  &lt;div class="SmallText" id="premain14" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="14" src="http://www.codeproject.com/images/minus.gif" id="preimg14" width="9" height="9" /&gt;&lt;span preid="14" style="margin-bottom: 0pt;" id="precollapse14"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt; color: rgb(255, 0, 0);" id="pre14" lang="xml"&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;system.web&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;trust&lt;/span&gt; &lt;span class="code-attribute"&gt;level&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;Full"&lt;/span&gt;&lt;span class="code-keyword"&gt;/&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;/pre&gt;  &lt;h2&gt;Making Best Use of Browser Cache &lt;/h2&gt;  &lt;h3&gt;Use URLs Consistently &lt;/h3&gt;  &lt;p style="text-align: justify;"&gt;Browsers cache content based on the URL. When the URL changes, the browser fetches a new version from origin server. URL can be changed by changing the query string parameters. For example, &lt;em&gt;/default.aspx&lt;/em&gt; is cached on the browser. If you request &lt;em&gt;/default.aspx?123&lt;/em&gt; it will fetch new content from the server. Response from the new URL can also be cached in the browser if you return proper caching headers. In that case, changing the query parameter to something else like &lt;em&gt;/default.aspx?456&lt;/em&gt; will return new content from the server. So, you need to make sure you use URL consistently everywhere when you want to get cached response. From homepage, if you have requested a file with URL &lt;em&gt;/welcome.gif&lt;/em&gt;, make sure from another page you request the same file using the same URL. One common mistake is to sometimes omit the �www� subdomain from the URL. &lt;a href="http://www.pageflakes.com/default.aspx" mce_href="http://www.pageflakes.com/default.aspx"&gt;www.ebay.com/default.aspx&lt;/a&gt; is not same as &lt;a href="http://www.pageflakes.com/default.aspx" mce_href="http://www.pageflakes.com/default.aspx"&gt;ebay.com/default.aspx&lt;/a&gt;. Both will be cached separately. &lt;/p&gt;  &lt;h3&gt;Cache Static Content for Longer Period &lt;/h3&gt;  &lt;p style="text-align: justify;"&gt;Static files can be cached for longer periods like one month. If you are thinking that you should cache for couple of days so that when you change the file, users will pick it up sooner, you're mistaken. If you update a file which was cached by &lt;code&gt;Expires &lt;/code&gt;header, new users will immediately get the new file while old users will see the old content until it expires on their browser. So, as long as you are using &lt;code style="color: rgb(255, 0, 0);"&gt;Expires &lt;/code&gt;header to cache static files, you should use as high a value as possible. &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;For example, if you have set &lt;code style="color: rgb(255, 0, 0);"&gt;Expires &lt;/code&gt;header to cache a file for three days, one user will get the file today and store it in cache for next three days. Another user will get the file tomorrow and cache it for three days after tomorrow. If you change the file on the day after tomorrow, the first user will see it on fourth day and the second user will see it on fifth day. So, different users will see different versions of the file. As a result, it does not help setting a lower value assuming all users will pick up the latest file soon. You will have to change the URL of the file in order to ensure everyone gets the exact same file immediately. &lt;/p&gt;  &lt;p&gt;You can setup &lt;code&gt;Expires&lt;/code&gt; header from static files from IIS Manager. You'll learn how to do it in a later section. &lt;/p&gt;  &lt;h3&gt;&lt;strong&gt;Use Cache Friendly Folder Structure&lt;/strong&gt; &lt;/h3&gt;  &lt;p style="text-align: justify;"&gt;Store cached content under a common folder. For example, store all images of your site under the &lt;em&gt;/static&lt;/em&gt; folder instead of storing images separately under different subfolders. This will help you use consistent URL throughout the site because from anywhere you can use &lt;em&gt;/static/images/somefile.gif&lt;/em&gt;. Later on, we will learn it�s easier to move to a Content Delivery Network when you have static cacheable files under a common root folder. &lt;/p&gt;  &lt;h3&gt;&lt;strong&gt;Reuse Common Graphics Files&lt;/strong&gt; &lt;/h3&gt;  &lt;p style="text-align: justify;"&gt;Sometimes we put common &lt;em&gt;graphics&lt;/em&gt; files under several virtual directories so that we can write smaller paths. For example, say you have &lt;em&gt;indicator.gif&lt;/em&gt; in &lt;em&gt;root&lt;/em&gt; folder, some subfolders and under &lt;em&gt;CSS&lt;/em&gt; folder. You did it because you need not worry about paths from different places and you could just use the file name as relative URL. This does not help in caching. Each copy of the file is cached in the browser separately. So, you should collect all graphics files in the whole solution and put them under the same root &lt;em&gt;static&lt;/em&gt; folder after eliminating duplicates and use the same URL from all the pages and CSS files. &lt;/p&gt;  &lt;h3&gt;&lt;strong&gt;Change File Name When You Want to Expire Cache&lt;/strong&gt; &lt;/h3&gt;  &lt;p style="text-align: justify;"&gt;When you want a &lt;em&gt;static&lt;/em&gt; file to be changed, don't just update the file because it�s already cached in the user�s browser. You need to change the file name and update all references everywhere so that browser downloads the new file. You can also store the file names in database or configuration files and use data binding to generate the URL dynamically. This way you can change the URL from one place and have the whole site receive the change immediately. &lt;/p&gt;  &lt;h3&gt;Use a Version Number While Accessing Static Files &lt;/h3&gt;  &lt;p style="text-align: justify;"&gt;If you do not want to clutter your &lt;em&gt;static&lt;/em&gt; folder with multiple copies of the same file, you can use query string to differentiate versions of same file. For example, a GIF can be accessed with a dummy query string like &lt;em&gt;/static/images/indicator.gif?v=1&lt;/em&gt;. When you change the &lt;em&gt;indicator.gif&lt;/em&gt;, you can overwrite the same file and then update all references to the file to &lt;em&gt;/static/images/indicator.gif?v=2&lt;/em&gt;. This way you can keep changing the same file again and again and just update the references to access the graphics using the new version number. &lt;/p&gt;  &lt;h3&gt;Store Cacheable Files in a Different Domain &lt;/h3&gt;  &lt;p style="text-align: justify;"&gt;It�s always a good idea to put static contents in a different domain. First of all, the browser can open other two concurrent connections to download the static files. Another benefit is that you don't need to send the cookies to the static files. When you put the static files on the same domain as your Web application, browser sends all the ASP.NET cookies and all other cookies that your Web application is producing. This makes the request headers unnecessarily large and waste bandwidth. You don't need to send these cookies to access the static files. So, if you put the static files in a different domain, those cookies will not be sent. For example, put your static files in &lt;a href="http://www.staticcontent.com/" mce_href="http://www.staticcontent.com/"&gt;www.staticcontent.com&lt;/a&gt; domain while your website is running on &lt;a href="http://www.dropthings.com/" mce_href="http://www.dropthings.com/"&gt;www.dropthings.com&lt;/a&gt;. The other domain does not need to be a completely different Web site. It can just be an alias and share the same Web application path. &lt;/p&gt;  &lt;h3&gt;&lt;strong&gt;SSL is Not Cached, so Minimize SSL Use&lt;/strong&gt; &lt;/h3&gt;  &lt;p style="text-align: justify;"&gt;Any content that is served over SSL is not cached. So, you need to put static content outside SSL. Moreover, you should try limiting SSL to only secure pages like Login page or Payment page. Rest of the site should be outside SSL over regular HTTP. SSL encrypts request and response and thus puts extra load on the server. Encrypted content is also larger than the original content and thus takes more bandwidth. &lt;/p&gt;  &lt;h3&gt;HTTP POST Requests are Never Cached &lt;/h3&gt;  &lt;p style="text-align: justify;"&gt;Cache only happens for HTTP &lt;code&gt;GET &lt;/code&gt;requests. HTTP &lt;code&gt;POST &lt;/code&gt;requests are never cached. So, any kind of AJAX call you want to make cacheable needs to be HTTP &lt;code&gt;GET &lt;/code&gt;enabled. &lt;/p&gt;  &lt;h3&gt;Generate Content-Length Response Header &lt;/h3&gt;  &lt;p style="text-align: justify;"&gt;When you are dynamically serving content via Web service calls or HTTP handlers, make sure you emit &lt;code&gt;Content-Length&lt;/code&gt; header. Browsers have several optimizations for downloading contents faster when it knows how many bytes to download from the response by looking at the &lt;code&gt;Content-Length&lt;/code&gt; header. Browsers can use persisted connections more effectively when this header is present. This saves the browser from opening a new connection for each request. When there�s no &lt;code&gt;Content-Length &lt;/code&gt;header, browser doesn't know how many bytes it�s going to receive from the server and thus keeps the connection open as long as it gets bytes delivered from the server until the connection closes. So, you miss the benefit of Persisted Connections that can greatly reduce download time of several small files like CS, JavaScripts, and images. &lt;/p&gt;  &lt;h3&gt;How to Configure Static Content Caching in IIS &lt;/h3&gt;  &lt;p style="text-align: justify;"&gt;In IIS Manager, Web site properties dialog box has �HTTP Headers� tab where you can define &lt;code&gt;Expires &lt;/code&gt;header for all requests that IIS handles. There you can define whether to expire content immediately or expire after certain number of days or on a specific date. The second option (Expire after) uses sliding expiration, not absolute expiration. This is very useful because it works per request. Whenever someone requests a static file, IIS will calculate the expiration date based on the number of days/months from the Expire after. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://omar.mvps.org/images/Makingbestuseofcacheforbestsiteperforman_15143/clip_image001.gif" mce_href="http://omar.mvps.org/images/Makingbestuseofcacheforbestsiteperforman_15143/clip_image001.gif"&gt;&lt;img alt="clip_image001" src="http://www.codeproject.com/KB/aspnet/10ASPNetPerformance/clip_image001_thumb.gif" mce_src="http://omar.mvps.org/images/Makingbestuseofcacheforbestsiteperforman_15143/clip_image001_thumb.gif" width="472" border="0" height="458" hspace="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;For dynamic pages that are served by ASP.NET, a handler can modify the &lt;code&gt;Expires &lt;/code&gt;header and override IIS default setting. &lt;/p&gt;  &lt;h2&gt;On Demand Progressive UI Loading for Fast Smooth Experience &lt;/h2&gt;  &lt;p style="text-align: justify;"&gt;AJAX websites are all about loading as many features as possible into the browser without having any postback. If you look at the Start Pages like &lt;a href="http://www.pageflakes.com/" mce_href="http://www.pageflakes.com"&gt;Pageflakes&lt;/a&gt;, it's only one single page that gives you all the features of the whole application with zero postback. A quick and dirty approach for doing this is to deliver every possible HTML snippet inside hidden &lt;code&gt;div&lt;/code&gt;s during page load and then make those &lt;code&gt;div&lt;/code&gt;s visible when needed. But this makes first time loading way too slow and browser gives sluggish performance as too much stuff is there to process on the DOM. So, a better approach is to load the HTML snippet and necessary JavaScript on-demand. In my &lt;a href="http://www.dropthings.com/" mce_href="http://www.dropthings.com"&gt;dropthings&lt;/a&gt; project, I have shown an example how this is done. &lt;/p&gt; &lt;img alt="clip_image002" src="http://www.codeproject.com/KB/aspnet/10ASPNetPerformance/clip_image002.gif" mce_src="http://omar.mvps.org/images/IncrementalUIloadingonAJAXwebsites_12E95/clip_image002.gif" width="480" border="0" height="424" hspace="0" /&gt;  &lt;p style="text-align: justify;"&gt;When you click on the "help" link, it loads the content of the help dynamically. This HTML is not delivered as part of the &lt;em&gt;default.aspx&lt;/em&gt; that renders the first page. Thus the giant HTML and graphics related to the help section has no effect on site load performance. It is only loaded when user clicks the "help" link. Moreover, it gets cached on the browser and thus loads only once. When user clicks the "help" link again, it's served directly from the browser cache, instead of fetching from the origin server again. &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;The principle is making an XMLHTTP call to an &lt;em&gt;*.aspx&lt;/em&gt; page, get the response HTML, put that response HTML inside a container &lt;code&gt;DIV&lt;/code&gt;, make that &lt;code&gt;DIV &lt;/code&gt;visible. &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;AJAX Framework has a &lt;code&gt;Sys.Net.WebRequest&lt;/code&gt; class which you can use to make regular HTTP calls. You can define HTTP method, URI, headers and the body of the call. It�s kind of a low level function for making direct calls via XMLHTTP. Once you construct a Web request, you can execute it using &lt;code&gt;Sys.Net.XMLHttpExecutor&lt;/code&gt;. &lt;/p&gt;  &lt;div class="SmallText" id="premain15" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="15" src="http://www.codeproject.com/images/minus.gif" id="preimg15" width="9" height="9" /&gt;&lt;span preid="15" style="margin-bottom: 0pt;" id="precollapse15"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre15" lang="cs"&gt;function showHelp()&lt;br /&gt;{&lt;br /&gt;var request = &lt;span class="code-keyword"&gt;new&lt;/span&gt; Sys.Net.WebRequest();&lt;br /&gt;request.set_httpVerb(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;GET"&lt;/span&gt;);&lt;br /&gt;request.set_url(&lt;span class="code-string"&gt;'&lt;/span&gt;&lt;span class="code-string"&gt;help.aspx'&lt;/span&gt;);&lt;br /&gt;request.add_completed( function( executor )&lt;br /&gt;{&lt;br /&gt;   &lt;span class="code-keyword"&gt;if&lt;/span&gt; (executor.get_responseAvailable())&lt;br /&gt;   {&lt;br /&gt;&lt;br /&gt;      var helpDiv = $get(&lt;span class="code-string"&gt;'&lt;/span&gt;&lt;span class="code-string"&gt;HelpDiv'&lt;/span&gt;);&lt;br /&gt;      var helpLink = $get(&lt;span class="code-string"&gt;'&lt;/span&gt;&lt;span class="code-string"&gt;HelpLink'&lt;/span&gt;);&lt;br /&gt;      var helpLinkBounds = Sys.UI.DomElement.getBounds(helpLink);&lt;br /&gt;&lt;br /&gt;      helpDiv.style.top = (helpLinkBounds.y + helpLinkBounds.height) + &lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;px"&lt;/span&gt;;&lt;br /&gt;      var content = executor.get_responseData();&lt;br /&gt;      helpDiv.innerHTML = content;&lt;br /&gt;      helpDiv.style.display = &lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;block"&lt;/span&gt;;                    &lt;br /&gt;&lt;br /&gt;   }&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;var executor = &lt;span class="code-keyword"&gt;new&lt;/span&gt; Sys.Net.XMLHttpExecutor();&lt;br /&gt;request.set_executor(executor);&lt;br /&gt;executor.executeRequest();&lt;br /&gt;}&lt;/pre&gt;  &lt;p style="text-align: justify;"&gt;The example shows how the help section is loaded by hitting &lt;code&gt;help.aspx&lt;/code&gt; and injecting its response inside the &lt;code&gt;HelpDiv&lt;/code&gt;. The response can be cached by the &lt;a&gt;output cache directive &lt;/a&gt;set on &lt;em&gt;help.aspx&lt;/em&gt;. So, next time when the user clicks on the link, the UI pops up immediately. The &lt;em&gt;help.aspx&lt;/em&gt; file has no &lt;code&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;html&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;/code&gt; block, only the content that is set inside the &lt;code&gt;&lt;a&gt;DIV&lt;/a&gt;&lt;/code&gt;. &lt;/p&gt;  &lt;div class="SmallText" id="premain16" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="16" src="http://www.codeproject.com/images/minus.gif" id="preimg16" width="9" height="9" /&gt;&lt;span preid="16" style="margin-bottom: 0pt;" id="precollapse16"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre16" lang="xml"&gt;&lt;span class="code-pagedirective"&gt;&lt;%@&lt;/span&gt;&lt;span class="code-leadattribute"&gt; Page Language&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;C#"&lt;/span&gt;&lt;span class="code-attribute"&gt; AutoEventWireup&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;true"&lt;/span&gt;&lt;span class="code-attribute"&gt; CodeFile&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;Help.aspx.cs"&lt;/span&gt;&lt;span class="code-attribute"&gt;&lt;br /&gt; Inherits&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;Help"&lt;/span&gt;&lt;span class="code-attribute"&gt; &lt;/span&gt;&lt;span class="code-pagedirective"&gt;%&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-pagedirective"&gt;&lt;%@&lt;/span&gt;&lt;span class="code-leadattribute"&gt; OutputCache Location&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;ServerAndClient"&lt;/span&gt;&lt;span class="code-attribute"&gt; Duration&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;604800"&lt;/span&gt;&lt;span class="code-attribute"&gt; VaryByParam&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;none"&lt;/span&gt;&lt;span class="code-attribute"&gt; &lt;/span&gt;&lt;span class="code-pagedirective"&gt;%&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;div&lt;/span&gt; &lt;span class="code-attribute"&gt;class&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;helpContent"&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;div&lt;/span&gt; &lt;span class="code-attribute"&gt;id&lt;/span&gt;&lt;span class="code-keyword"&gt;="&lt;/span&gt;&lt;span class="code-keyword"&gt;lipsum"&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;&lt;&lt;/span&gt;&lt;span class="code-leadattribute"&gt;p&lt;/span&gt;&lt;span class="code-keyword"&gt;&gt;&lt;/span&gt;&lt;br /&gt;Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis lorem&lt;br /&gt;eros, volutpat sit amet, venenatis vitae, condimentum at, dolor. Nunc&lt;br /&gt;porttitor eleifend tellus. Praesent vitae neque ut mi rutrum cursus.&lt;/pre&gt;  &lt;p style="text-align: justify;"&gt;Using this approach, you can break the UI into smaller &lt;em&gt;*.aspx &lt;/em&gt;files. Although these &lt;em&gt;*.aspx &lt;/em&gt;files cannot have JavaScript or stylesheet blocks, they can contain large amount of HTML that you need to show on the UI on-demand. Thus you can keep initial download to absolute minimum just for loading the basic stuff. When the user explores new features on the site, load those areas incrementally. &lt;/p&gt;  &lt;h2&gt;Optimize ASP.NET 2.0 Profile Provider &lt;/h2&gt;  &lt;p style="text-align: justify;"&gt;Do you know there are two important stored procedures in ASP.NET 2.0 Profile Provider that you can optimize significantly? If you use them without doing the necessary optimization, your servers will sink taking your business down with you during heavy load. Here's a story: &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;During March, &lt;a href="http://www.pageflakes.com/" mce_href="http://www.pageflakes.com"&gt;Pageflakes&lt;/a&gt; was shown on MIX 2006. We were having a glamorous time back then. We were right on &lt;a href="http://atlas.asp.net/default.aspx?tabid=47&amp;amp;subtabid=472" mce_href="http://atlas.asp.net/default.aspx?tabid=47&amp;amp;subtabid=472"&gt;Showcase of Atlas Web site&lt;/a&gt; as the first company. Number of visits per day were rising sky high. One day we noticed, the database server was no more. We restarted the server, brought it back, again it died within an hour. After doing a lot of postmortem analysis on the remains of the server's body parts, we found that it was having 100% CPU and super high IO usage. The hard drives were over heated and turned themselves off in order to save themselves. This was quite surprising to us because we thought we were very intelligent back then and we used to profile every single Web service function. So, we went through hundreds of megabytes of logs hoping to find which webservice function was taking the time. We suspected one. It was the first function that loads a user's page setup. We broke it up into smaller parts in order to see which part is taking most of the time. &lt;/p&gt;  &lt;div class="SmallText" id="premain17" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="17" src="http://www.codeproject.com/images/minus.gif" id="preimg17" width="9" height="9" /&gt;&lt;span preid="17" style="margin-bottom: 0pt;" id="precollapse17"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre17" lang="cs"&gt;&lt;span class="code-keyword"&gt;private&lt;/span&gt; GetPageflake(&lt;span class="code-keyword"&gt;string&lt;/span&gt; source, &lt;span class="code-keyword"&gt;string&lt;/span&gt; pageID, &lt;span class="code-keyword"&gt;string&lt;/span&gt; userUniqueName)&lt;br /&gt;{&lt;br /&gt;&lt;span class="code-keyword"&gt;if&lt;/span&gt;( Profile.IsAnonymous )&lt;br /&gt;{&lt;br /&gt;&lt;span class="code-keyword"&gt;using&lt;/span&gt; (&lt;span class="code-keyword"&gt;new&lt;/span&gt; TimedLog(Profile.UserName,&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;GetPageflake"&lt;/span&gt;))&lt;br /&gt;{&lt;/pre&gt;  &lt;p style="text-align: justify;"&gt;You see, the entire function body is timed. If you want to learn how this timing works, I will explain it in a new article. We also timed smaller parts which we suspected were taking the most resource. But we could find not a single place in our code which was taking any significant time. Our codebase is always super optimized (after all, you know who is reviewing it, me). &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;Meanwhile, users were shouting, management was screaming, support staff was complaining on the phone. Developers were furiously sweating and blood vessels on their forehead were coming out. Nothing special, just a typical situation we have couple of times every month. &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;Now you must be shouting, "You could have used SQL Profiler, you idiot!" We were using SQL Server workgroup edition. It does not have SQL Profiler. So, we had to hack our way through to get it running on a server somehow. Don't ask how. After running the SQL Profiler, boy, were we surprised! The name of the honorable SP which was giving us so much pain was the great stored procedure &lt;code&gt;dbo.aspnet_Profile_GetProfiles&lt;/code&gt;! &lt;/p&gt;  &lt;p&gt;We used (and still use) Profile provider extensively. &lt;/p&gt;  &lt;p&gt;Here's the SP: &lt;/p&gt;  &lt;div class="SmallText" id="premain18" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="18" src="http://www.codeproject.com/images/minus.gif" id="preimg18" width="9" height="9" /&gt;&lt;span preid="18" style="margin-bottom: 0pt;" id="precollapse18"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre18" lang="sql"&gt;&lt;span class="code-keyword"&gt;CREATE&lt;/span&gt; &lt;span class="code-keyword"&gt;PROCEDURE&lt;/span&gt; [dbo].[aspnet_Profile_GetProfiles]&lt;br /&gt;@ApplicationName &lt;span class="code-keyword"&gt;nvarchar&lt;/span&gt;(&lt;span class="code-digit"&gt;256&lt;/span&gt;),&lt;br /&gt; @ProfileAuthOptions &lt;span class="code-keyword"&gt;int&lt;/span&gt;,&lt;br /&gt; @PageIndex  &lt;span class="code-keyword"&gt;int&lt;/span&gt;,&lt;br /&gt; @PageSize   &lt;span class="code-keyword"&gt;int&lt;/span&gt;,&lt;br /&gt; @UserNameToMatch   &lt;span class="code-keyword"&gt;nvarchar&lt;/span&gt;(&lt;span class="code-digit"&gt;256&lt;/span&gt;) = &lt;span class="code-keyword"&gt;NULL&lt;/span&gt;,&lt;br /&gt; @InactiveSinceDate &lt;span class="code-keyword"&gt;datetime&lt;/span&gt; = &lt;span class="code-keyword"&gt;NULL&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;AS&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;BEGIN&lt;/span&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;DECLARE&lt;/span&gt; @ApplicationId &lt;span class="code-keyword"&gt;uniqueidentifier&lt;/span&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;SELECT&lt;/span&gt; @ApplicationId = &lt;span class="code-keyword"&gt;NULL&lt;/span&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;SELECT&lt;/span&gt; @ApplicationId = ApplicationId&lt;br /&gt;             &lt;span class="code-keyword"&gt;FROM&lt;/span&gt; aspnet_Applications&lt;br /&gt;                 &lt;span class="code-keyword"&gt;WHERE&lt;/span&gt; LOWER(@ApplicationName)&lt;br /&gt;                         = LoweredApplicationName&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;IF&lt;/span&gt; (@ApplicationId &lt;span class="code-keyword"&gt;IS&lt;/span&gt; &lt;span class="code-keyword"&gt;NULL&lt;/span&gt;)&lt;br /&gt;     &lt;span class="code-keyword"&gt;RETURN&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;--&lt;/span&gt;&lt;span class="code-comment"&gt; Set the page bounds&lt;/span&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;DECLARE&lt;/span&gt; @PageLowerBound &lt;span class="code-keyword"&gt;int&lt;/span&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;DECLARE&lt;/span&gt; @PageUpperBound &lt;span class="code-keyword"&gt;int&lt;/span&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;DECLARE&lt;/span&gt; @TotalRecords   &lt;span class="code-keyword"&gt;int&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;SET&lt;/span&gt; @PageLowerBound = @PageSize * @PageIndex&lt;br /&gt;&lt;span class="code-keyword"&gt;SET&lt;/span&gt; @PageUpperBound = @PageSize - &lt;span class="code-digit"&gt;1&lt;/span&gt; + @PageLowerBound&lt;br /&gt;&lt;br /&gt; &lt;span class="code-comment"&gt;--&lt;/span&gt;&lt;span class="code-comment"&gt; Create a temp table TO store the select results&lt;/span&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;CREATE&lt;/span&gt; &lt;span class="code-keyword"&gt;TABLE&lt;/span&gt; #PageIndexForUsers&lt;br /&gt; (&lt;br /&gt;   IndexId &lt;span class="code-keyword"&gt;int&lt;/span&gt; &lt;span class="code-keyword"&gt;IDENTITY&lt;/span&gt; (&lt;span class="code-digit"&gt;0&lt;/span&gt;, &lt;span class="code-digit"&gt;1&lt;/span&gt;) &lt;span class="code-keyword"&gt;NOT&lt;/span&gt; &lt;span class="code-keyword"&gt;NULL&lt;/span&gt;,&lt;br /&gt;   UserId &lt;span class="code-keyword"&gt;uniqueidentifier&lt;/span&gt;&lt;br /&gt; )&lt;br /&gt;&lt;br /&gt; &lt;span class="code-comment"&gt;--&lt;/span&gt;&lt;span class="code-comment"&gt; Insert into our temp table&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;INSERT&lt;/span&gt; &lt;span class="code-keyword"&gt;INTO&lt;/span&gt; #PageIndexForUsers (UserId)&lt;br /&gt; &lt;br /&gt;   &lt;span class="code-keyword"&gt;SELECT&lt;/span&gt; u.UserId&lt;br /&gt;     &lt;span class="code-keyword"&gt;FROM&lt;/span&gt;    dbo.aspnet_Users&lt;br /&gt;         u, dbo.aspnet_Profile p&lt;br /&gt;   &lt;span class="code-keyword"&gt;WHERE&lt;/span&gt;   ApplicationId = @ApplicationId&lt;br /&gt;         &lt;span class="code-keyword"&gt;AND&lt;/span&gt; u.UserId = p.UserId    &lt;br /&gt;             &lt;span class="code-keyword"&gt;AND&lt;/span&gt; (@InactiveSinceDate&lt;br /&gt;             &lt;span class="code-keyword"&gt;IS&lt;/span&gt; &lt;span class="code-keyword"&gt;NULL&lt;/span&gt; &lt;span class="code-keyword"&gt;OR&lt;/span&gt; LastActivityDate&lt;br /&gt;                     &lt;= @InactiveSinceDate)                &lt;span class="code-keyword"&gt;AND&lt;/span&gt; (&lt;br /&gt;                 (@ProfileAuthOptions = &lt;span class="code-digit"&gt;2&lt;/span&gt;)&lt;br /&gt;             &lt;span class="code-keyword"&gt;OR&lt;/span&gt; (@ProfileAuthOptions = &lt;span class="code-digit"&gt;0&lt;/span&gt;&lt;br /&gt;                     &lt;span class="code-keyword"&gt;AND&lt;/span&gt; IsAnonymous = &lt;span class="code-digit"&gt;1&lt;/span&gt;)&lt;br /&gt;             &lt;span class="code-keyword"&gt;OR&lt;/span&gt; (@ProfileAuthOptions = &lt;span class="code-digit"&gt;1&lt;/span&gt;&lt;br /&gt;                     &lt;span class="code-keyword"&gt;AND&lt;/span&gt; IsAnonymous = &lt;span class="code-digit"&gt;0&lt;/span&gt;)&lt;br /&gt;                 )&lt;br /&gt;             &lt;span class="code-keyword"&gt;AND&lt;/span&gt; (@UserNameToMatch&lt;br /&gt;             &lt;span class="code-keyword"&gt;IS&lt;/span&gt; &lt;span class="code-keyword"&gt;NULL&lt;/span&gt; &lt;span class="code-keyword"&gt;OR&lt;/span&gt; LoweredUserName&lt;br /&gt;                 &lt;span class="code-keyword"&gt;LIKE&lt;/span&gt; LOWER(@UserNameToMatch))&lt;br /&gt;     &lt;span class="code-keyword"&gt;ORDER&lt;/span&gt; &lt;span class="code-keyword"&gt;BY&lt;/span&gt; UserName&lt;br /&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;SELECT&lt;/span&gt; u.UserName, u.IsAnonymous, u.LastActivityDate,&lt;br /&gt;   p.LastUpdatedDate, DATALENGTH(p.PropertyNames)&lt;br /&gt;   + DATALENGTH(p.PropertyValuesString)&lt;br /&gt;   + DATALENGTH(p.PropertyValuesBinary)&lt;br /&gt; &lt;span class="code-keyword"&gt;FROM&lt;/span&gt;    dbo.aspnet_Users&lt;br /&gt;                 u, dbo.aspnet_Profile p, #PageIndexForUsers i&lt;br /&gt; &lt;span class="code-keyword"&gt;WHERE&lt;/span&gt;&lt;br /&gt;   u.UserId = p.UserId&lt;br /&gt;   &lt;span class="code-keyword"&gt;AND&lt;/span&gt; p.UserId = i.UserId&lt;br /&gt;   &lt;span class="code-keyword"&gt;AND&lt;/span&gt; i.IndexId &gt;= @PageLowerBound&lt;br /&gt;   &lt;span class="code-keyword"&gt;AND&lt;/span&gt; i.IndexId &lt;= @PageUpperBound     &lt;span class="code-keyword"&gt;DROP&lt;/span&gt; &lt;span class="code-keyword"&gt;TABLE&lt;/span&gt; #PageIndexForUsers&lt;br /&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;END&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;END&lt;/span&gt; &lt;/pre&gt;  &lt;p&gt;First it looks up for &lt;code&gt;ApplicationID&lt;/code&gt;. &lt;/p&gt;  &lt;div class="SmallText" id="premain19" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="19" src="http://www.codeproject.com/images/minus.gif" id="preimg19" width="9" height="9" /&gt;&lt;span preid="19" style="margin-bottom: 0pt;" id="precollapse19"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre19" lang="sql"&gt;   &lt;span class="code-keyword"&gt;DECLARE&lt;/span&gt; @ApplicationId  &lt;span class="code-keyword"&gt;uniqueidentifier&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;SELECT&lt;/span&gt; @ApplicationId = &lt;span class="code-keyword"&gt;NULL&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;SELECT&lt;/span&gt; @ApplicationId = ApplicationId &lt;span class="code-keyword"&gt;FROM&lt;/span&gt; aspnet_Applications&lt;br /&gt;&lt;span class="code-keyword"&gt;WHERE&lt;/span&gt; LOWER(@ApplicationName) = LoweredApplicationName&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;IF&lt;/span&gt; (@ApplicationId &lt;span class="code-keyword"&gt;IS&lt;/span&gt; &lt;span class="code-keyword"&gt;NULL&lt;/span&gt;)&lt;br /&gt;   &lt;span class="code-keyword"&gt;RETURN&lt;/span&gt;&lt;/pre&gt;  &lt;p&gt;Then it creates a temporary table (it should use table data type) in order to store profiles of users. &lt;/p&gt;  &lt;div class="SmallText" id="premain20" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="20" src="http://www.codeproject.com/images/minus.gif" id="preimg20" width="9" height="9" /&gt;&lt;span preid="20" style="margin-bottom: 0pt;" id="precollapse20"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre20" lang="sql"&gt;    &lt;span class="code-comment"&gt;--&lt;/span&gt;&lt;span class="code-comment"&gt; Create a temp table TO store the select results&lt;/span&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;CREATE&lt;/span&gt; &lt;span class="code-keyword"&gt;TABLE&lt;/span&gt; #PageIndexForUsers&lt;br /&gt; (&lt;br /&gt;     IndexId &lt;span class="code-keyword"&gt;int&lt;/span&gt; &lt;span class="code-keyword"&gt;IDENTITY&lt;/span&gt; (&lt;span class="code-digit"&gt;0&lt;/span&gt;, &lt;span class="code-digit"&gt;1&lt;/span&gt;) &lt;span class="code-keyword"&gt;NOT&lt;/span&gt; &lt;span class="code-keyword"&gt;NULL&lt;/span&gt;,&lt;br /&gt;   UserId &lt;span class="code-keyword"&gt;uniqueidentifier&lt;/span&gt;&lt;br /&gt; )&lt;br /&gt;&lt;span class="code-comment"&gt;--&lt;/span&gt;&lt;span class="code-comment"&gt; Insert into our temp table&lt;/span&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;INSERT&lt;/span&gt; &lt;span class="code-keyword"&gt;INTO&lt;/span&gt; #PageIndexForUsers (UserId)&lt;/pre&gt;  &lt;p style="text-align: justify;"&gt;If it gets called very frequently, there will be too high IO due to the temporary table creation. It also runs through two very big tables - &lt;code&gt;aspnet_Users &lt;/code&gt;and &lt;code&gt;aspnet_Profile&lt;/code&gt;. The SP is written in such a way that if one user has multiple profiles, it will return all profiles of the user. But normally we store one profile per user. So, there's no need for creating a temporary table. Moreover, there's no need for doing &lt;code&gt;LIKE LOWER(@UserNameToMatch)&lt;/code&gt;. We always called with a full user name which we can match directly using the &lt;code&gt;equal &lt;/code&gt;operator. &lt;/p&gt;  &lt;p&gt;So, we opened up the stored proc and did a open heart bypass surgery like this: &lt;/p&gt;  &lt;div class="SmallText" id="premain21" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="21" src="http://www.codeproject.com/images/minus.gif" id="preimg21" width="9" height="9" /&gt;&lt;span preid="21" style="margin-bottom: 0pt;" id="precollapse21"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre21" lang="sql"&gt;&lt;span class="code-keyword"&gt;IF&lt;/span&gt; @UserNameToMatch &lt;span class="code-keyword"&gt;IS&lt;/span&gt; &lt;span class="code-keyword"&gt;NOT&lt;/span&gt; &lt;span class="code-keyword"&gt;NULL&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;BEGIN&lt;/span&gt;&lt;br /&gt;     &lt;span class="code-keyword"&gt;SELECT&lt;/span&gt; u.UserName, u.IsAnonymous, u.LastActivityDate, p.LastUpdatedDate,&lt;br /&gt;   DATALENGTH(p.PropertyNames)&lt;br /&gt;     + DATALENGTH(p.PropertyValuesString) + DATALENGTH(p.PropertyValuesBinary)&lt;br /&gt;   &lt;span class="code-keyword"&gt;FROM&lt;/span&gt;    dbo.aspnet_Users u&lt;br /&gt;     &lt;span class="code-keyword"&gt;INNER&lt;/span&gt; &lt;span class="code-keyword"&gt;JOIN&lt;/span&gt; dbo.aspnet_Profile p &lt;span class="code-keyword"&gt;ON&lt;/span&gt; u.UserId = p.UserId&lt;br /&gt;   &lt;span class="code-keyword"&gt;WHERE&lt;/span&gt; u.LoweredUserName = LOWER(@UserNameToMatch)&lt;br /&gt;&lt;br /&gt;     &lt;span class="code-keyword"&gt;SELECT&lt;/span&gt; &lt;span class="code-preprocessor"&gt;@@ROWCOUNT&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;END&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;ELSE&lt;/span&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;BEGIN&lt;/span&gt; &lt;span class="code-comment"&gt;--&lt;/span&gt;&lt;span class="code-comment"&gt; Do the original bad things&lt;/span&gt;&lt;/pre&gt;  &lt;p style="text-align: justify;"&gt;It ran fine locally. Now it was time to run it on the server. This is an important SP which is used by the ASP.NET 2.0 Profile Provider, heart of ASP.NET Framework. If we do something wrong here, we might not be able to see the problem immediately, but may be after one month we will realize users profile is mixed up and there's no way to get it back. So, it was a pretty hard decision to run this on a live production server directly without doing enough testing. We did not have time to do enough testing anyway. We are already down. So, we all gathered, said our prayers and hit the "Execute" button on SQL Server Management Studio. &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;The SP ran fine. On the server we noticed from 100% CPU usage it came down to 30% CPU usage. IO usage also came down to 40%. &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;We went live again! &lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;Here's another SP that gets called on every page load and webservice call on our site because we use Profile provider extensively. &lt;/p&gt;  &lt;div class="SmallText" id="premain22" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="22" src="http://www.codeproject.com/images/minus.gif" id="preimg22" width="9" height="9" /&gt;&lt;span preid="22" style="margin-bottom: 0pt;" id="precollapse22"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre22" lang="sql"&gt;&lt;span class="code-keyword"&gt;CREATE&lt;/span&gt; &lt;span class="code-keyword"&gt;PROCEDURE&lt;/span&gt; [dbo].[aspnet_Profile_GetProperties]&lt;br /&gt; @ApplicationName   &lt;span class="code-keyword"&gt;nvarchar&lt;/span&gt;(&lt;span class="code-digit"&gt;256&lt;/span&gt;),&lt;br /&gt; @UserName  &lt;span class="code-keyword"&gt;nvarchar&lt;/span&gt;(&lt;span class="code-digit"&gt;256&lt;/span&gt;),&lt;br /&gt; @CurrentTimeUtc  &lt;span class="code-keyword"&gt;datetime&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;AS&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;BEGIN&lt;/span&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;DECLARE&lt;/span&gt; @ApplicationId &lt;span class="code-keyword"&gt;uniqueidentifier&lt;/span&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;SELECT&lt;/span&gt; @ApplicationId = &lt;span class="code-keyword"&gt;NULL&lt;/span&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;SELECT&lt;/span&gt; @ApplicationId = ApplicationId&lt;br /&gt;             &lt;span class="code-keyword"&gt;FROM&lt;/span&gt; dbo.aspnet_Applications&lt;br /&gt;                     &lt;span class="code-keyword"&gt;WHERE&lt;/span&gt; LOWER(@ApplicationName) = LoweredApplicationName&lt;br /&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;IF&lt;/span&gt; (@ApplicationId &lt;span class="code-keyword"&gt;IS&lt;/span&gt; &lt;span class="code-keyword"&gt;NULL&lt;/span&gt;)&lt;br /&gt;     &lt;span class="code-keyword"&gt;RETURN&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;DECLARE&lt;/span&gt; @UserId &lt;span class="code-keyword"&gt;uniqueidentifier&lt;/span&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;SELECT&lt;/span&gt; @UserId = &lt;span class="code-keyword"&gt;NULL&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;SELECT&lt;/span&gt; @UserId = UserId&lt;br /&gt; &lt;span class="code-keyword"&gt;FROM&lt;/span&gt;   dbo.aspnet_Users&lt;br /&gt; &lt;span class="code-keyword"&gt;WHERE&lt;/span&gt; ApplicationId = @ApplicationId&lt;br /&gt;             &lt;span class="code-keyword"&gt;AND&lt;/span&gt; LoweredUserName =&lt;br /&gt;                     LOWER(@UserName)&lt;br /&gt; &lt;span class="code-keyword"&gt;IF&lt;/span&gt; (@UserId &lt;span class="code-keyword"&gt;IS&lt;/span&gt; &lt;span class="code-keyword"&gt;NULL&lt;/span&gt;)&lt;br /&gt;     &lt;span class="code-keyword"&gt;RETURN&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;SELECT&lt;/span&gt; &lt;span class="code-keyword"&gt;TOP&lt;/span&gt; &lt;span class="code-digit"&gt;1&lt;/span&gt; PropertyNames, PropertyValuesString, PropertyValuesBinary&lt;br /&gt; &lt;span class="code-keyword"&gt;FROM&lt;/span&gt;         dbo.aspnet_Profile&lt;br /&gt; &lt;span class="code-keyword"&gt;WHERE&lt;/span&gt;        UserId = @UserId&lt;br /&gt;&lt;br /&gt; &lt;span class="code-keyword"&gt;IF&lt;/span&gt; (&lt;span class="code-preprocessor"&gt;@@ROWCOUNT&lt;/span&gt; &gt; &lt;span class="code-digit"&gt;0&lt;/span&gt;)&lt;br /&gt; &lt;span class="code-keyword"&gt;BEGIN&lt;/span&gt;&lt;br /&gt;     &lt;span class="code-keyword"&gt;UPDATE&lt;/span&gt; dbo.aspnet_Users&lt;br /&gt;     &lt;span class="code-keyword"&gt;SET&lt;/span&gt;    LastActivityDate=@CurrentTimeUtc&lt;br /&gt;     &lt;span class="code-keyword"&gt;WHERE&lt;/span&gt; UserId = @UserId&lt;br /&gt; &lt;span class="code-keyword"&gt;END&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;END&lt;/span&gt;&lt;/pre&gt;  &lt;p&gt;When you run the SP, see the statistics: &lt;/p&gt;  &lt;div class="SmallText" id="premain23" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="23" src="http://www.codeproject.com/images/minus.gif" id="preimg23" width="9" height="9" /&gt;&lt;span preid="23" style="margin-bottom: 0pt;" id="precollapse23"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre23" lang="text"&gt;Table 'aspnet_Applications'. Scan count 1, logical reads 2, physical reads 0,&lt;br /&gt;                     read-ahead reads 0, lob logical reads 0, lob physical&lt;br /&gt;                         reads 0, lob read-ahead reads 0.&lt;br /&gt;(1 row(s) affected)&lt;br /&gt;Table 'aspnet_Users'. Scan count 1, logical reads 4, physical reads 0,&lt;br /&gt;                     read-ahead reads 0, lob logical reads 0, lob physical&lt;br /&gt;                         reads 0, lob read-ahead reads 0.&lt;br /&gt;&lt;br /&gt;(1 row(s) affected)&lt;br /&gt;(1 row(s) affected)&lt;br /&gt;Table 'aspnet_Profile'. Scan count 0, logical reads 3, physical reads 0,&lt;br /&gt;                     read-ahead reads 0, lob logical reads 0, lob physical&lt;br /&gt;                         reads 0, lob read-ahead reads 0.&lt;br /&gt;(1 row(s) affected)&lt;br /&gt;Table 'aspnet_Users'. Scan count 0, logical reads 27, physical reads 0,&lt;br /&gt;                     read-ahead reads 0, lob logical reads 0, lob physical&lt;br /&gt;                         reads 0, lob read-ahead reads 0.&lt;br /&gt;(1 row(s) affected)&lt;br /&gt;(1 row(s) affected)&lt;/pre&gt;  &lt;p style="text-align: justify;"&gt;This stored proc populates the &lt;code&gt;Profile&lt;/code&gt; object with all the custom properties whenever &lt;code&gt;Profile &lt;/code&gt;object is accessed for the first time within a request. &lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;First it does a &lt;code&gt;SELECT &lt;/code&gt;on &lt;code&gt;aspnet_application&lt;/code&gt; to find out the application ID from application name. You can easily replace this with a hard coded application ID inside the SP and save some effort. Normally we run only one application on our production server. So, there's no need to lookup application ID on every single call. This is one quick optimization to do. However, from client statistics, you can see where's the real performance bottleneck: &lt;/p&gt; &lt;img alt="Client_20statistics.png" src="http://www.codeproject.com/KB/aspnet/10ASPNetPerformance/Client_20statistics.png" width="559" border="0" height="326" hspace="0" /&gt;  &lt;p style="text-align: justify;"&gt;Then look at the last block where &lt;code&gt;aspnet_users&lt;/code&gt; table is updated with &lt;code&gt;LastActivityDate&lt;/code&gt;. This is the most expensive one. &lt;/p&gt; &lt;img alt="Update_20cost.png" src="http://www.codeproject.com/KB/aspnet/10ASPNetPerformance/Update_20cost.png" width="600" border="0" height="119" hspace="0" /&gt;  &lt;p style="text-align: justify;"&gt;This is done in order to ensure Profile provider remembers when was the last time a user's profile was accessed. We do not need to do this on every single page load and Web service call where Profile object is accessed. Maybe we can do it when user first logs in and logs out. In our case, a lot of Web service is called while user is on the page. There's only one page anyway. So, we can easily remove this in order to save a costly update on the giant &lt;code&gt;aspnet_users&lt;/code&gt; table on every single Web service call.&lt;/p&gt;  &lt;h2&gt;How to Query ASP.NET 2.0 Membership Tables Without Bringing Down the Site&lt;/h2&gt;  &lt;p&gt;Such queries will happily run on your development environment: &lt;/p&gt;  &lt;div class="SmallText" id="premain24" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="24" src="http://www.codeproject.com/images/minus.gif" id="preimg24" width="9" height="9" /&gt;&lt;span preid="24" style="margin-bottom: 0pt;" id="precollapse24"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre24" lang="sql"&gt;&lt;span class="code-keyword"&gt;Select&lt;/span&gt; * &lt;span class="code-keyword"&gt;from&lt;/span&gt; aspnet_users &lt;span class="code-keyword"&gt;where&lt;/span&gt; UserName = &lt;span class="code-string"&gt;'&lt;/span&gt;&lt;span class="code-string"&gt;blabla'&lt;/span&gt;&lt;/pre&gt;  &lt;p&gt;Or you can get some user's profile without any problem using: &lt;/p&gt;  &lt;div class="SmallText" id="premain25" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="25" src="http://www.codeproject.com/images/minus.gif" id="preimg25" width="9" height="9" /&gt;&lt;span preid="25" style="margin-bottom: 0pt;" id="precollapse25"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre25" lang="sql"&gt;&lt;span class="code-keyword"&gt;Select&lt;/span&gt; * &lt;span class="code-keyword"&gt;from&lt;/span&gt; aspnet_profile &lt;span class="code-keyword"&gt;where&lt;/span&gt; userID = &lt;span class="code-string"&gt;'&lt;/span&gt;&lt;span class="code-string"&gt;�...'&lt;/span&gt;&lt;/pre&gt;  &lt;p&gt;Even you can nicely update a user's email in &lt;code&gt;aspnet_membership&lt;/code&gt; table like this: &lt;/p&gt;  &lt;div class="SmallText" id="premain26" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="26" src="http://www.codeproject.com/images/minus.gif" id="preimg26" width="9" height="9" /&gt;&lt;span preid="26" style="margin-bottom: 0pt;" id="precollapse26"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre26" lang="sql"&gt;&lt;span class="code-keyword"&gt;Update&lt;/span&gt; aspnet_membership&lt;br /&gt;&lt;span class="code-keyword"&gt;SET&lt;/span&gt; Email = &lt;span class="code-string"&gt;'&lt;/span&gt;&lt;span class="code-string"&gt;newemailaddress@somewhere.com'&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;Where&lt;/span&gt; Email = &lt;span class="code-string"&gt;'&lt;/span&gt;&lt;span class="code-string"&gt;�'&lt;/span&gt;&lt;/pre&gt;  &lt;p style="text-align: justify;"&gt;But when you have a giant database on your production server, running any of these will bring your server down. The reason is, although these queries look like very obvious ones that you will be using frequently, none of these are part of any index. So, all of the above results in "Table Scan" (worst case for any query) on millions of rows on respective tables. &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;Here's what happened to us. We used such fields like &lt;code&gt;UserName&lt;/code&gt;, &lt;code&gt;Email&lt;/code&gt;, &lt;code&gt;UserID&lt;/code&gt;, &lt;code&gt;IsAnonymous&lt;/code&gt; etc. on lots of marketing reports at &lt;a href="http://www.pageflakes.com/" mce_href="http://www.pageflakes.com"&gt;Pageflakes&lt;/a&gt;. These are some reports which only marketing team use, no one else. Now, the site runs fine but several times a day marketing team and users used to call us and scream "Site is slow!", "Users are reporting extreme slow performance!", "Some pages are getting timed out!" etc. Usually when they call us, we tell them "Hold on, checking right now" and we check the site thoroughly. We use SQL profiler to see what's going wrong. But we cannot find any problem anywhere. Profiler shows queries running file. CPU load is within parameters. Site runs nice and smooth. We tell them on the phone, "We can't see any problem, what's wrong?" &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;So, why can't we see any slowness when we try to investigate the problem but the site becomes really slow several times throughout the day when we are not investigating? &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;Marketing team sometimes run analysis reports that use queries like the above several times per day. Whenever they run any of those queries, as the fields are not part of any index, it makes server IO go super high and CPU also goes super high - something like this: &lt;/p&gt; &lt;img src="http://www.codeproject.com/KB/aspnet/10ASPNetPerformance/clip_image001_thumb2.png" mce_src="http://omar.mvps.org/images/203b504bbfce_14EA7/clip_image001_thumb2.png" width="600" border="0" height="180" hspace="0" /&gt;  &lt;p style="text-align: justify;"&gt;We have SCSI drives which have 15000 RPM, very expensive, very fast. CPU is Dual core Dual Xeon 64bit. Both are very powerful hardware of their kind. Still these queries bring us down due to huge database size. &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;But this never happens when marketing team calls us and we keep them on the phone and try to find out what's wrong. Because when they are calling us and talking to us, &lt;strong&gt;they are not running any of the reports which bring the servers down&lt;/strong&gt;. They are working somewhere else on the site, mostly trying to do the same things complaining users are doing. &lt;/p&gt;  &lt;p&gt;Let's look at the indexes: &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;&lt;code&gt;Table: aspnet_users&lt;/code&gt; &lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;Clustered Index = &lt;code&gt;ApplicationID&lt;/code&gt;, &lt;code&gt;LoweredUserName&lt;/code&gt;&lt;/li&gt;&lt;li&gt;NonClustered Index = &lt;code&gt;ApplicationID&lt;/code&gt;, &lt;code&gt;LastActivityDate&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Primary Key = &lt;code&gt;UserID &lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;&lt;code&gt;Table: aspnet_membership&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;Clustered Index = &lt;code&gt;ApplicationID&lt;/code&gt;, &lt;code&gt;LoweredEmail&lt;/code&gt;&lt;/li&gt;&lt;li&gt;NonClustered = &lt;code&gt;UserID &lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;&lt;code&gt;Table: aspnet_Profile&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;ul style="text-align: justify;"&gt;&lt;li&gt;Clustered Index = &lt;code&gt;UserID &lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;Most of the indexes have &lt;code&gt;ApplicationID&lt;/code&gt; in it. Unless you put &lt;code&gt;ApplicationID=&lt;span class="code-string"&gt;'&lt;/span&gt;&lt;span class="code-string"&gt;�'&lt;/span&gt;&lt;/code&gt; in the &lt;code&gt;WHERE &lt;/code&gt;clause, it's not going to use any of the indexes. As a result, all the queries will suffer from Table Scan. Just put &lt;code&gt;ApplicationID&lt;/code&gt; in the &lt;code&gt;where &lt;/code&gt;clause (Find your &lt;code&gt;ApplicationID&lt;/code&gt; from &lt;code&gt;aspnet_Application&lt;/code&gt; table) and all the queries will become blazingly fast. &lt;/p&gt;  &lt;div style="text-align: justify;"&gt;&lt;strong&gt;DO NOT use &lt;code&gt;Email &lt;/code&gt;or &lt;code&gt;UserName &lt;/code&gt;fields in &lt;code&gt;WHERE &lt;/code&gt;clause. They are not part of the index instead &lt;code&gt;LoweredUserName &lt;/code&gt;and &lt;code&gt;LoweredEmail &lt;/code&gt;fields are in conjunction with &lt;code&gt;ApplicationID &lt;/code&gt;field. All queries must have &lt;code&gt;ApplicationID &lt;/code&gt;in the &lt;code&gt;WHERE &lt;/code&gt;clause.&lt;/strong&gt;&lt;/div&gt;&lt;p&gt; &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;Our Admin site which contains several of such reports and each contains lots of such queries on &lt;code&gt;aspnet_users&lt;/code&gt;, &lt;code&gt;aspnet_membership&lt;/code&gt; and &lt;code&gt;aspnet_Profile&lt;/code&gt; tables. As a result, whenever marketing team tried to generated reports, they took all the power of the CPU and HDD and the rest of the site became very slow and sometimes non-responsive. &lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;Make sure you always cross check all your queries &lt;code&gt;WHERE &lt;/code&gt;and &lt;code&gt;JOIN &lt;/code&gt;clauses with index configurations. Otherwise you are doomed for sure when you go live. &lt;/p&gt;  &lt;h2&gt;Prevent Denial of Service (DOS) Attack&lt;/h2&gt;  &lt;p style="text-align: justify;"&gt;Web services are the most attractive target for hackers because even a pre-school hacker can bring down a server by repeatedly calling a Web service which does expensive work. Ajax Start Pages like &lt;a href="http://www.pageflakes.com/" mce_href="http://www.pageflakes.com/"&gt;Pageflakes&lt;/a&gt; are the best target for such DOS attack because if you just visit the homepage repeatedly without preserving cookie, every hit is producing a brand new user, new page setup, new widgets and what not. The first visit experience is the most expensive one. Nonetheless, it�s the easiest one to exploit and bring down the site. You can try this yourself. Just write a simple code like this: &lt;/p&gt;  &lt;div class="SmallText" id="premain27" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="27" src="http://www.codeproject.com/images/minus.gif" id="preimg27" width="9" height="9" /&gt;&lt;span preid="27" style="margin-bottom: 0pt;" id="precollapse27"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre27" lang="cs"&gt;&lt;span class="code-keyword"&gt;for&lt;/span&gt;( &lt;span class="code-keyword"&gt;int&lt;/span&gt; i = &lt;span class="code-digit"&gt;0&lt;/span&gt;; i &lt; &lt;span class="code-digit"&gt;100000&lt;/span&gt;; i ++ )&lt;br /&gt;{&lt;br /&gt;WebClient client = &lt;span class="code-keyword"&gt;new&lt;/span&gt; WebClient();&lt;br /&gt;client.DownloadString(&lt;span class="code-string"&gt;"&lt;/span&gt;&lt;span class="code-string"&gt;http://www.pageflakes.com/default.aspx"&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;  &lt;p style="text-align: justify;"&gt;To your great surprise, you will notice that, after a couple of calls, you don't get a valid response. It�s not that you have succeeded in bringing down the server. It�s that your requests are being rejected. You are happy that you no longer get any service, thus you achieve Denial of Service (for yourself). We are happy to Deny You of Service (DYOS). &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;The trick I have in my sleeve is an inexpensive way to remember how many requests are coming from a particular IP. When the number of request exceeds the threshold, deny further request for some duration. The idea is to remember caller�s IP in ASP.NET Cache and maintain a count of request per IP. When the count exceeds a predefined limit, reject further request for some specific duration like 10 mins. After 10 mins, again allow requests from that IP. &lt;/p&gt;  &lt;p style="text-align: justify;"&gt;I have a class named &lt;code&gt;ActionValidator&lt;/code&gt; which maintains a count of specific actions like First Visit, Revisit, Asynchronous postbacks, Add New widget, Add New Page etc. It checks whether the count for such specific action for a specific IP exceeds the threshold value or not. &lt;/p&gt;  &lt;div class="SmallText" id="premain28" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="28" src="http://www.codeproject.com/images/minus.gif" id="preimg28" width="9" height="9" /&gt;&lt;span preid="28" style="margin-bottom: 0pt;" id="precollapse28"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre28" lang="cs"&gt;&lt;span class="code-keyword"&gt;public&lt;/span&gt; &lt;span class="code-keyword"&gt;static&lt;/span&gt; &lt;span class="code-keyword"&gt;class&lt;/span&gt; ActionValidator&lt;br /&gt;{&lt;br /&gt;  &lt;span class="code-keyword"&gt;private&lt;/span&gt; &lt;span class="code-keyword"&gt;const&lt;/span&gt; &lt;span class="code-keyword"&gt;int&lt;/span&gt; DURATION = &lt;span class="code-digit"&gt;10&lt;/span&gt;; &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; 10 min period&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="code-keyword"&gt;public&lt;/span&gt; &lt;span class="code-keyword"&gt;enum&lt;/span&gt; ActionTypeEnum&lt;br /&gt;  {&lt;br /&gt;      FirstVisit = &lt;span class="code-digit"&gt;100&lt;/span&gt;, &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; The most expensive one, choose the value wisely. &lt;/span&gt;&lt;br /&gt;      ReVisit = &lt;span class="code-digit"&gt;1000&lt;/span&gt;,  &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Welcome to revisit as many times as user likes&lt;/span&gt;&lt;br /&gt;      Postback = &lt;span class="code-digit"&gt;5000&lt;/span&gt;,    &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Not must of a problem for us&lt;/span&gt;&lt;br /&gt;      AddNewWidget = &lt;span class="code-digit"&gt;100&lt;/span&gt;,&lt;br /&gt;      AddNewPage = &lt;span class="code-digit"&gt;100&lt;/span&gt;,&lt;br /&gt;  }&lt;/pre&gt;  &lt;p style="text-align: justify;"&gt;The enumeration contains the type of actions to check for and their threshold value for a specific duration � 10 mins. &lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;A &lt;code&gt;&lt;span class="code-keyword"&gt;static&lt;/span&gt; &lt;/code&gt;method named &lt;code&gt;IsValid&lt;/code&gt; does the check. It returns &lt;code&gt;&lt;span class="code-keyword"&gt;true&lt;/span&gt; &lt;/code&gt;if the request limit is not passed, &lt;code&gt;&lt;span class="code-keyword"&gt;false&lt;/span&gt; &lt;/code&gt;if the request needs to be denied. Once you get &lt;code&gt;&lt;span class="code-keyword"&gt;false&lt;/span&gt;&lt;/code&gt;, you can call &lt;code&gt;Request.End()&lt;/code&gt; and prevent ASP.NET from proceeding further. You can also switch to a page which shows �Congratulations! You have succeeded in Denial of Service Attack.� &lt;/p&gt;  &lt;div class="SmallText" id="premain29" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="29" src="http://www.codeproject.com/images/minus.gif" id="preimg29" width="9" height="9" /&gt;&lt;span preid="29" style="margin-bottom: 0pt;" id="precollapse29"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre29" lang="cs"&gt;&lt;span class="code-keyword"&gt;public&lt;/span&gt; &lt;span class="code-keyword"&gt;static&lt;/span&gt; &lt;span class="code-keyword"&gt;bool&lt;/span&gt; IsValid( ActionTypeEnum actionType )&lt;br /&gt;{&lt;br /&gt;HttpContext context = HttpContext.Current;&lt;br /&gt;&lt;span class="code-keyword"&gt;if&lt;/span&gt;( context.Request.Browser.Crawler ) &lt;span class="code-keyword"&gt;return&lt;/span&gt; &lt;span class="code-keyword"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;string&lt;/span&gt; key = actionType.ToString() + context.Request.UserHostAddress;&lt;br /&gt;var hit = (HitInfo)(context.Cache[key] ?? &lt;span class="code-keyword"&gt;new&lt;/span&gt; HitInfo());&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;if&lt;/span&gt;( hit.Hits &gt; (&lt;span class="code-keyword"&gt;int&lt;/span&gt;)actionType ) &lt;span class="code-keyword"&gt;return&lt;/span&gt; &lt;span class="code-keyword"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;span class="code-keyword"&gt;else&lt;/span&gt; hit.Hits ++;&lt;br /&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;if&lt;/span&gt;( hit.Hits == &lt;span class="code-digit"&gt;1&lt;/span&gt; )&lt;br /&gt;   context.Cache.Add(key, hit, &lt;span class="code-keyword"&gt;null&lt;/span&gt;, DateTime.Now.AddMinutes(DURATION),&lt;br /&gt;      System.Web.Caching.Cache.NoSlidingExpiration,&lt;br /&gt;      System.Web.Caching.CacheItemPriority.Normal, &lt;span class="code-keyword"&gt;null&lt;/span&gt;);&lt;br /&gt;&lt;span class="code-keyword"&gt;return&lt;/span&gt; &lt;span class="code-keyword"&gt;true&lt;/span&gt;;&lt;br /&gt;}&lt;/pre&gt;  &lt;p style="text-align: justify;"&gt;The cache key is built with a combination of action type and client IP address. First it checks if there�s any entry for the action and the client IP in &lt;code&gt;cache &lt;/code&gt;or not. If not, start the count and remember the count for the IP in cache for the specific duration. The absolute expiration on &lt;code&gt;cache &lt;/code&gt;item ensures that after the duration the &lt;code&gt;cache &lt;/code&gt;item will be cleared and the count will restart. When there�s already an entry in the &lt;code&gt;cache&lt;/code&gt;, get the last hit count, and check if the limit is exceeded or not. If not exceeded, increase the counter. There is no need to store the updated value in the &lt;code&gt;cache &lt;/code&gt;again by doing: &lt;code&gt;Cache[url]=hit&lt;/code&gt;; because the hit object is by reference and changing it means it gets changed in the cache as well. In fact, if you do put it again in the &lt;code&gt;cache&lt;/code&gt;, the &lt;code&gt;cache&lt;/code&gt; expiration counter will restart and fail the logic of restarting count after specific duration. &lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;The usage is very simple, on the &lt;em&gt;default.aspx&lt;/em&gt;: &lt;/p&gt;  &lt;div class="SmallText" id="premain30" style="width: 100%; cursor: pointer;"&gt;&lt;img preid="30" src="http://www.codeproject.com/images/minus.gif" id="preimg30" width="9" height="9" /&gt;&lt;span preid="30" style="margin-bottom: 0pt;" id="precollapse30"&gt; Collapse&lt;/span&gt;&lt;/div&gt;&lt;pre style="margin-top: 0pt;" id="pre30" lang="cs"&gt;&lt;span class="code-keyword"&gt;protected&lt;/span&gt; &lt;span class="code-keyword"&gt;override&lt;/span&gt; &lt;span class="code-keyword"&gt;void&lt;/span&gt; OnInit(EventArgs e)&lt;br /&gt;{&lt;br /&gt;&lt;span class="code-keyword"&gt;base&lt;/span&gt;.OnInit(e);&lt;br /&gt;&lt;br /&gt;&lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Check if revisit is valid or not&lt;/span&gt;&lt;br /&gt;&lt;span class="code-keyword"&gt;if&lt;/span&gt;( !base.IsPostBack )&lt;br /&gt;{&lt;br /&gt;   &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Block cookie less visit attempts&lt;/span&gt;&lt;br /&gt;   &lt;span class="code-keyword"&gt;if&lt;/span&gt;( Profile.IsFirstVisit )&lt;br /&gt;   {&lt;br /&gt;      &lt;span class="code-keyword"&gt;if&lt;/span&gt;( !ActionValidator.IsValid(ActionValidator.ActionTypeEnum.FirstVisit))&lt;br /&gt;         Response.End();&lt;br /&gt;   }&lt;br /&gt;   &lt;span class="code-keyword"&gt;else&lt;/span&gt;&lt;br /&gt;   {&lt;br /&gt;      &lt;span class="code-keyword"&gt;if&lt;/span&gt;( !ActionValidator.IsValid(ActionValidator.ActionTypeEnum.ReVisit) )&lt;br /&gt;         Response.End();&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;span class="code-keyword"&gt;else&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;   &lt;span class="code-comment"&gt;//&lt;/span&gt;&lt;span class="code-comment"&gt; Limit number of postbacks&lt;/span&gt;&lt;br /&gt;   &lt;span class="code-keyword"&gt;if&lt;/span&gt;( !ActionValidator.IsValid(ActionValidator.ActionTypeEnum.Postback) )&lt;br /&gt;         Response.End();&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;  &lt;p style="text-align: justify;"&gt;Here I am checking specific scenario like first Visit, re-visit, postbacks etc. &lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;Of course you can put in some Cisco firewall and prevent DOS attack. You will get a guarantee from your hosting provider that their entire network is immune to DOS and DDOS (Distributed DOS) attacks. What they guarantee is network level attack like TCP SYN attacks or malformed packet floods etc. There is no way they can analyze the packet and find out a particular IP is trying to load the site too many times without supporting cookie or trying to add too many widgets. These are called application level DOS attack which hardware cannot prevent. It must be implemented in your own code. &lt;/p&gt;&lt;div style="text-align: justify;"&gt;  &lt;/div&gt;&lt;p style="text-align: justify;"&gt;There are very few websites out there which take such precaution for application level DOS attacks. Thus it�s quite easy to make servers go mad by writing a simple loop and hitting expensive pages or Web services continuously from your home broadband connection. I hope this small but effective class will help you prevent DOS attack in your own Web applications. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/864116869953733620-6209059112612659496?l=narulaamitsk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://narulaamitsk.blogspot.com/feeds/6209059112612659496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=864116869953733620&amp;postID=6209059112612659496' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/6209059112612659496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/6209059112612659496'/><link rel='alternate' type='text/html' href='http://narulaamitsk.blogspot.com/2009/06/10-aspnet-performance-and-scalability.html' title='10 ASP.NET Performance and Scalability Secrets'/><author><name>Amit Narula</name><uri>http://www.blogger.com/profile/03373886236261160868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_KIFo2nRsLTc/SfIq-GgjUkI/AAAAAAAACCo/bBDItRMEB6s/S220/DSCF1775.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-864116869953733620.post-3426466128244468351</id><published>2009-06-03T03:08:00.000-07:00</published><updated>2009-06-03T03:09:59.389-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>WCF Contracts Defined</title><content type='html'>&lt;span style="font-family: verdana; font-size: 85%;"&gt;A WCF service publishes the operations that it supports by using a &lt;strong&gt;service contract&lt;/strong&gt;. This contract defines the operations that the service provides, without specifying how the operations should be implemented.&lt;br /&gt;&lt;br /&gt;Operations are defined by adding methods to a &lt;strong&gt;Service Contract&lt;/strong&gt; interface that is annotated with the &lt;strong&gt;OperationContract&lt;/strong&gt; attribute. Only methods that are qualified by the &lt;strong&gt;OperationContract&lt;/strong&gt; attribute are service operations, and can be exposed to clients.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&lt;br /&gt;[ServiceContract]&lt;br /&gt;public interface IOrderService {&lt;br /&gt;  [OperationContract]&lt;br /&gt;  void CreateOrder(int orderNumber);&lt;br /&gt;  [OperationContract]&lt;br /&gt;  void AddItemToOrder(int orderNumber, Item itm);&lt;br /&gt;  [OperationContract]&lt;br /&gt;  Order GetOrderDetails(int orderNumber);&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: verdana; font-size: 85%;"&gt;&lt;br /&gt;A WCF service is implemented by creating a class that implements the service interface.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 85%; font-family: courier new;"&gt;&lt;br /&gt;public class OrderService : IOrderService {&lt;br /&gt;  void CreateOrder(int orderNumber) {&lt;br /&gt;    // implementation details&lt;br /&gt;  }&lt;br /&gt;  void AddItemToOrder(int orderNumber, Item itm) {&lt;br /&gt;    // implementation details&lt;br /&gt;  }&lt;br /&gt;  Order GetOrderDetails(int orderNumber) {&lt;br /&gt;    // implementation details&lt;br /&gt;  }&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: verdana; font-size: 85%;"&gt;&lt;br /&gt;&lt;strong&gt;Data contracts&lt;/strong&gt; define how complex types are serialized when they are used in WCF service operations. They defined by applying the &lt;strong&gt;DataContract&lt;/strong&gt; attribute to a class, and then adding &lt;strong&gt;DataMember&lt;/strong&gt; attributes to fields and properties to show which members are to be exposed to clients.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&lt;br /&gt;[DataContract]&lt;br /&gt;public class Order {&lt;br /&gt;  [DataMember]&lt;br /&gt;  public int OrderNumber;&lt;br /&gt;  [DataMember]&lt;br /&gt;  public String ClientName;&lt;br /&gt;  ...&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: verdana; font-size: 85%;"&gt;&lt;br /&gt;&lt;strong&gt;Message contracts&lt;/strong&gt; describe the entire SOAP message format. They can use data contracts and serializable types to emit schema for complex types, and they also make it possible to control the SOAP message headers and body explicitly, by using a single type. Message contracts provide a simple method to add custom SOAP headers to incoming and outgoing messages.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&lt;br /&gt;[MessageContract]&lt;br /&gt;public class MyRequest {&lt;br /&gt;  [MessageHeader]&lt;br /&gt;  public string field1;&lt;br /&gt;  [MessageBody]&lt;br /&gt;  public string field2;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: verdana; font-size: 85%;"&gt;&lt;br /&gt;A WCF service reports errors by using &lt;strong&gt;Fault&lt;/strong&gt; objects. &lt;strong&gt;Fault contracts&lt;/strong&gt; document the errors that WCF code is likely to produce, and WCF maps Fault objects to SOAP faults. Note that the type specified in the FaultContract does not have to be an exception.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&lt;br /&gt;[OperationContract]&lt;br /&gt;[FaultContract(typeof(DivideByZeroException))]&lt;br /&gt;void SomeMethod();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: verdana; font-size: 85%;"&gt;&lt;br /&gt;A Fault is generated by throwing a &lt;strong&gt;FaultException&lt;/strong&gt;:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new; font-size: 85%;"&gt;&lt;br /&gt;throw new FaultException&lt;dividebyzeroexception&gt;(someException);&lt;/dividebyzeroexception&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/864116869953733620-3426466128244468351?l=narulaamitsk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://narulaamitsk.blogspot.com/feeds/3426466128244468351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=864116869953733620&amp;postID=3426466128244468351' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/3426466128244468351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/3426466128244468351'/><link rel='alternate' type='text/html' href='http://narulaamitsk.blogspot.com/2009/06/wcf-contracts-defined.html' title='WCF Contracts Defined'/><author><name>Amit Narula</name><uri>http://www.blogger.com/profile/03373886236261160868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_KIFo2nRsLTc/SfIq-GgjUkI/AAAAAAAACCo/bBDItRMEB6s/S220/DSCF1775.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-864116869953733620.post-4012718248215410211</id><published>2009-06-01T11:06:00.000-07:00</published><updated>2009-06-01T11:50:33.283-07:00</updated><title type='text'>Abstract Class and An Interface</title><content type='html'>&lt;h2&gt;Background&lt;/h2&gt;  &lt;p&gt;An Abstract class without any implementation just looks like an Interface; however there are lot of differences than similarities between an Abstract class and an Interface. Let's explain both concepts and compare their similarities and differences.&lt;/p&gt;  &lt;h3&gt;What is an Abstract Class?&lt;/h3&gt;  &lt;p&gt;An abstract class is a special kind of class that cannot be instantiated. So the question is why we need a class that cannot be instantiated? An abstract class is only to be sub-classed (inherited from). In other words, it only allows other classes to inherit from it but cannot be instantiated. The advantage is that it enforces certain hierarchies for all the subclasses. In simple words, it is a kind of contract that forces all the subclasses to carry on the same hierarchies or standards.&lt;/p&gt;  &lt;h3&gt;What is an Interface?&lt;/h3&gt;  &lt;p&gt;An interface is not a class. It is an entity that is defined by the word Interface. An interface has no implementation; it only has the signature or in other words, just the definition of the methods without the body. As one of the similarities to Abstract class, it is a contract that is used to define hierarchies for all subclasses or it defines specific set of methods and their arguments. The main difference between them is that a class can implement more than one interface but can only inherit from one abstract class. Since C# doesn�t support multiple inheritance, interfaces are used to implement multiple inheritance.&lt;/p&gt;  &lt;h3&gt;Both Together&lt;/h3&gt;  &lt;p&gt;When we create an interface, we are basically creating a set of methods without any implementation that must be overridden by the implemented classes. The advantage is that it provides a way for a class to be a part of two classes: one from inheritance hierarchy and one from the interface.&lt;/p&gt;  &lt;p&gt;When we create an abstract class, we are creating a base class that might have one or more completed methods but at least one or more methods are left uncompleted and declared &lt;code&gt;&lt;span class="code-keyword"&gt;abstract&lt;/span&gt;&lt;/code&gt;. If all the methods of an abstract class are uncompleted then it is same as an interface. The purpose of an abstract class is to provide a base class definition for how a set of derived classes will work and then allow the programmers to fill the implementation in the derived classes.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;There are some similarities and differences between an interface and an abstract class that I have arranged in a table for easier comparison:&lt;/p&gt;  &lt;table style="width: 587px; height: 797px;" class="ArticleTable" cellpadding="7" cellspacing="0"&gt; &lt;thead&gt; &lt;tr&gt; &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;Feature&lt;/p&gt; &lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;Interface&lt;/p&gt; &lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;Abstract class&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt; &lt;/thead&gt;  &lt;tbody&gt; &lt;tr&gt; &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;Multiple inheritance&lt;/p&gt; &lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;A class may inherit several interfaces.&lt;/p&gt; &lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;A class may inherit only one abstract class.&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;Default implementation&lt;/p&gt; &lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;An interface cannot provide any code, just the signature.&lt;/p&gt; &lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;An abstract class can provide complete, default code and/or just the details that have to be overridden.&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td style="text-align: left;" valign="top" width="33%"&gt;Access Modfiers&lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt;An interface cannot have access modifiers for the subs, functions, properties etc everything is assumed as public&lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt;An abstract class can contain access modifiers for the subs, functions, properties&lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;Core VS Peripheral&lt;/p&gt; &lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;Interfaces are used to define the peripheral abilities of a class. In other words both Human and Vehicle can inherit from a IMovable interface.&lt;/p&gt; &lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;An abstract class defines the core identity of a class and there it is used for objects of the same type.&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;Homogeneity&lt;/p&gt; &lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;If various implementations only share method signatures then it is better to use Interfaces.&lt;/p&gt; &lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;If various implementations are of the same kind and use common behaviour or status then abstract class is better to use.&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;Speed&lt;/p&gt; &lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;Requires more time to find the actual method in the corresponding classes.&lt;/p&gt; &lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;Fast&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;Adding functionality (Versioning)&lt;/p&gt; &lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;If we add a new method to an Interface then we have to track down all the implementations of the interface and define implementation for the new method.&lt;/p&gt; &lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt; &lt;p&gt;If we add a new method to an abstract class then we have the option of providing default implementation and therefore all the existing code might work properly.&lt;/p&gt; &lt;/td&gt; &lt;/tr&gt;  &lt;tr&gt; &lt;td style="text-align: left;" valign="top" width="33%"&gt;Fields and Constants&lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt;No fields can be defined in interfaces&lt;/td&gt;  &lt;td style="text-align: left;" valign="top" width="33%"&gt;An abstract class can have fields and constrants defined&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt;  &lt;h2&gt;&lt;br /&gt;&lt;/h2&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/864116869953733620-4012718248215410211?l=narulaamitsk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://narulaamitsk.blogspot.com/feeds/4012718248215410211/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=864116869953733620&amp;postID=4012718248215410211' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/4012718248215410211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/4012718248215410211'/><link rel='alternate' type='text/html' href='http://narulaamitsk.blogspot.com/2009/06/abstract-class-and-interface.html' title='Abstract Class and An Interface'/><author><name>Amit Narula</name><uri>http://www.blogger.com/profile/03373886236261160868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_KIFo2nRsLTc/SfIq-GgjUkI/AAAAAAAACCo/bBDItRMEB6s/S220/DSCF1775.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-864116869953733620.post-8630218705539378096</id><published>2009-05-27T07:25:00.000-07:00</published><updated>2009-05-27T07:32:17.117-07:00</updated><title type='text'>DataBase Naming Conventions</title><content type='html'>&lt;p style="text-align: justify;"&gt;&lt;font size="6"&gt;&lt;font color="#000080"&gt;&lt;font size="5" face="Verdana"&gt;Database Naming Conventions Version&lt;/font&gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#808080" size="2" face="Verdana"&gt;&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;The main goal of adopting a naming convention for database objects is so that you and others can easily identify the type and purpose of all objects contained in the database. The information presented here serves as a guide for you to follow when naming your database objects. When reading these rules and guidelines remember that consistent naming can be the most important rule to follow. Keep in mind that  following the guidelines as outlined in this document can still produce long and cryptic names, ultimately, your unique situation will dictate the reasonability of your naming convention. The goal of this particular naming convention is to produce practical, legible, concise, unambiguous and consistent names for your database objects.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;While most databases contain more types of objects than those discussed here (User Defined Types, Functions, Queries, etc.), the 7 types of objects mentioned here are common among all major database systems. Think of this as a generic DBMS-neutral guide for naming your objects. &lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;The following types of database objects are discussed here:&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;ol style="text-align: justify;"&gt;&lt;li&gt;&lt;a href="http://weblogs.asp.net/jamauss/pages/DatabaseNamingConventions.aspx#Tables"&gt;&lt;font face="Verdana"&gt;Tables&lt;/font&gt;&lt;/a&gt;&lt;font face="Verdana"&gt; &lt;/font&gt; &lt;/li&gt;&lt;li&gt;&lt;font face="Verdana"&gt;&lt;a href="http://weblogs.asp.net/jamauss/pages/DatabaseNamingConventions.aspx#Columns"&gt;Columns&lt;/a&gt; (incl. Primary, Foreign and Composite Keys) &lt;/font&gt; &lt;/li&gt;&lt;li&gt;&lt;font face="Verdana"&gt;&lt;a href="http://weblogs.asp.net/jamauss/pages/DatabaseNamingConventions.aspx#Indexes"&gt;Indexes&lt;/a&gt; &lt;/font&gt; &lt;/li&gt;&lt;li&gt;&lt;font face="Verdana"&gt;&lt;a href="http://weblogs.asp.net/jamauss/pages/DatabaseNamingConventions.aspx#Constraints"&gt;Constraints&lt;/a&gt; &lt;/font&gt; &lt;/li&gt;&lt;li&gt;&lt;font face="Verdana"&gt;&lt;a href="http://weblogs.asp.net/jamauss/pages/DatabaseNamingConventions.aspx#Views"&gt;Views&lt;/a&gt; &lt;/font&gt; &lt;/li&gt;&lt;li&gt;&lt;font face="Verdana"&gt;&lt;a href="http://weblogs.asp.net/jamauss/pages/DatabaseNamingConventions.aspx#StoredProcedures"&gt;Stored Procedures&lt;/a&gt; &lt;/font&gt; &lt;/li&gt;&lt;li&gt;&lt;font face="Verdana"&gt;&lt;a href="http://weblogs.asp.net/jamauss/pages/DatabaseNamingConventions.aspx#Triggers"&gt;Triggers&lt;/a&gt;&lt;/font&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font color="#a52a2a" size="4" face="Verdana"&gt;&lt;strong&gt;ALL DATABASE OBJECTS&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;&lt;font face="Verdana"&gt;Limit the name to 30 characters (shorter is better)&lt;/font&gt;  &lt;/li&gt;&lt;li&gt;&lt;font face="Verdana"&gt;Use only letters or underscores (try to avoid numbers)&lt;/font&gt;  &lt;/li&gt;&lt;li&gt;&lt;font face="Verdana"&gt;Try to use underscore characters as little as possible. PascalCase notation achieves the same word separation without them.  &lt;/font&gt;&lt;/li&gt;&lt;font face="Verdana"&gt;&lt;li&gt;Use a letter as the first character of the name. (don't start names with underscores)  &lt;/li&gt;&lt;li&gt;Avoid abbreviations (can lead to misinterpretation of names)  &lt;/li&gt;&lt;li&gt;Avoid acronyms (some acronyms have more than one meaning eg. "ASP")  &lt;/li&gt;&lt;li&gt;Makes the name readable (they shouldn't sound funny when read aloud)  &lt;/li&gt;&lt;li&gt;Avoid using spaces in names even if the system allows it.&lt;/li&gt;&lt;/font&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;a name="Tables"&gt;&lt;font color="#a52a2a" size="4" face="Verdana"&gt;&lt;strong&gt;1. TABLES&lt;/strong&gt;&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;&lt;font face="Verdana"&gt;When naming your database tables, give consideration to other steps in the development process. Keep in mind you will most likely have to utilize the names you give your tables several times as part of other objects, for example, procedures, triggers or views may all contain references to the table name. You want to keep the name as simple and short as possible. Some systems enforce character limits on object names also. For example, in Oracle you are limited to about 30 characters per object.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 1a&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Plural Names&lt;/em&gt;) - Table names should be plural, for example, "Customers" instead of "Customer". This rule is applicable because tables are logical collections of one or more entities as records - just like collection classes are logical collections of one or more objects. If you were to first draw an abstract data model like a NIAM/ORM model, you might have singular entity names like "Customer" or "User" but, they should be changed to the plural form when building the actual tables. For table names with multiple words, only the last word should be plural, for example, "UserRoles" and "UserRoleSettings".&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 1b&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Prefixes&lt;/em&gt;) - Used correctly, table prefixes can help you organize your tables into related groups or distinguish them from other unrelated tables. Used poorly, they can cause you to have to type a lot of unnecessary characters. We'll discuss what not to do first. Do not give your table names prefixes like "tbl" or "TBL_" as these are just redundant and unnecessary. It will be obvious which names are the table names in SQL statements because they will always be proceeded by the FROM clause of the SELECT statement. Not all prefixes are bad. In some cases, your tables might be sharing a schema/database with other tables that are not related in any way. In this case, it is sometimes a good idea to prefix your table names with some characters that group your tables together. For example, for a healthcare application you might give your tables an "Hc" prefix so that all of the tables for that application would appear in alphabetized lists together. Note that even for the prefix, use Pascal Case. This is discussed in Rule 1c. Do not use underscores in your prefixes, which is discussed in more depth in Rule 1d. The last kind of prefix that is acceptable is one that allows you to group logical units of tables. A plausible example could entail a large application (30 to 40+ tables) that handled both Payroll and Benefits data. You could prefix the tables dealing with payroll with a "Pay" or "Prl" prefix and give the tables dealing with benefits data a "Ben" or "Bfts" prefix. The goal of both this prefix and the aforementioned shared schema/database prefix is to allow you to group specific tables together alphabetically in lists and distinguish them from unrelated tables. Lastly, the shared schema/database prefix is a higher grouping level and comes first in the name, for example, "HcPayClients" not "PayHcClients".&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 1c&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Notation&lt;/em&gt;) - For all parts of the table name, including prefixes, use Pascal Case. Using this notation will distinguish your table names from SQL keywords (all capital letters). For example, "SELECT CustomerId_Pk, CustomerName FROM MyAppGroupTable WHERE CustomerName = '%S'" shows the notation for the table name distinguishing it from the SQL keywords used in the query. PascalCase also reduces the need for underscores to visually separate words in names.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 1d&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Special Characters&lt;/em&gt;) - For table names, underscores should not be used. The underscore character has a place in other object names but, not for tables. Using Pascal Case for your table name allows for the upper-case letter to denote the first letter of a new word or name. Thus there is no need to do so with an underscore character. Do not use numbers in your table names either. This usually points to a poorly designed data model or irregularly partitioned tables. Do not use spaces in your table names either. While most database systems can handle names that include spaces, some systems require you to add more characters around the name when referencing it (like [table name] for example) which goes against the rule of keeping things as short and simple as possible. If you are developing in a non-english language, do not use any of that language's special characters.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 1e&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Abbreviations&lt;/em&gt;) - Avoid using abbreviations if possible. Use "Accounts" instead of "Accts" and "Hours" instead of "Hrs". Not everyone will always agree with you on what your abbrevations stand for - and - this makes it simple to read and understand for both developers and non-developers. This rule can be relaxed for junction table names (See Rule 1f). Do not use acronyms.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 1f&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Junction a.k.a Intersection Tables&lt;/em&gt;) - Junction tables, which handle many to many relationships, should be named by concatenating the names of the tables that have a one to many relationship with the junction table. For example, you might have "Doctors" and "Patients" tables. Since doctors can have many patients and patients can have many doctors (specialists) you need a table to hold the data for those relationships in a junction table. This table should be named DoctorsPatients". Since this convention can result in lengthy table names, abbreviations sometimes may be used at your discretion.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;a name="Columns"&gt;&lt;font color="#a52a2a" size="4"&gt;&lt;strong&gt;2. COLUMNS&lt;/strong&gt;&lt;/font&gt;&lt;/a&gt; - (&lt;em&gt;incl. PRIMARY, FOREIGN, AND COMPOSITE KEYS&lt;/em&gt;)&lt;br /&gt;When naming your columns, keep in mind that they are members of the table, so they do not need the any mention of the table name in the name. The primary key field is typically the only exception to this rule where including the table name is justified so that you can have a more descriptive field name than just "Id". "CustomerId" is acceptable but not required. Just like with naming tables, avoid using abbreviations, acronyms or special characters. All column names should use Pascal Case to distinguish them from SQL keywords (all upper case). &lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 2a&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Identity Primary Key Fields&lt;/em&gt;) - For fields that are the primary key for a table and uniquely identify each record in the table, the name should simply be “Id“ since, that's what it is - an identification field. This name also maps more closely to a property name like “Id“ in your class libraries. Another benefit of this name is that for joins you will see something like&lt;br /&gt;      "Customers JOIN Orders ON Customer.Id = Orders.CustomerId“&lt;br /&gt;which allows you to avoid the word “Customer“ again after the Customer table.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 2b&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Foreign Key Fields&lt;/em&gt;) - Foreign key fields should have the exact same name as they do in the parent table where the field is the primary key - with one exception - the table name should be specified. For example, in the Customers table the primary key field might be "Id". In an Orders table where the customer id is kept, it would be "CustomerId". There is one exception to this rule, which is when you have more than one foreign key field per table referencing the same primary key field in another table. In this situation, it might be helpful to add a descriptor before the field name. An example of this is if you had an Address table. You might have another table with foreign key fields like HomeAddressId, WorkAddressId, MailingAddressId, or ShippingAddressId. &lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 2c&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Composite Keys&lt;/em&gt;) - If you have tables with composite keys (more than one field makes up the unique value) then instead of just “Id“ you should use a descriptor before the “Id“ characters. Two fields like “ModuleId“ and “CodeId“ might make up the composite key, for example. If you don't see an “Id“ column in the table - you'll know that a composite key is used to uniquely identify records.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 2d&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Prefixes&lt;/em&gt;) - Do not prefix your fields with "fld_" or "Col_" as it should be obvious in SQL statements which items are columns (before or after the FROM clause). Including a two or three character data type prefix for the field is optional and not recommended, for example, "IntCustomerId" for a numeric type or "VcName" for a varchar type. However, these data type abbreviations are DBMS specific and are outside the scope of this document.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 2e&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Data Type Specific Naming&lt;/em&gt;) - Boolean fields should be given names like "IsDeleted", "HasPermission", or "IsValid" so that the meaning of the data in the field is not ambiguous. If the field holds date and/or time information, the word "Date" or "Time" should appear somewhere in the field name. It is sometimes appropriate to add the unit of time to the field name also, especially if the field holds data like whole numbers ("3" or "20"). Those fields should be named like "RuntimeHours" or "ScheduledMinutes".&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;a name="Indexes"&gt;&lt;font color="#a52a2a" size="4"&gt;&lt;strong&gt;3. INDEXES&lt;/strong&gt;&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;Since indexes are always related to a table or view, it makes the most sense to use the name of the table or view, as well as the column(s) they index, in the index name, along with some characters that specify the type of index it is. This naming convention also allows you, if looking at a list of indexes, to see the indexes ordered by table, then column, then index type.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 3a&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Naming Convention&lt;/em&gt;) - The naming convention for indexes follows this structure:&lt;br /&gt;&lt;br /&gt;     {TableName}{ColumnsIndexed}{U/N}{C/N}&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;where "U/N" is for unique or non-unique and "C/N" is for clustered or non-clustered. This naming convention is unique among database objects, so adding characters to denote it being an index, like "idx" is not necessary. The naming convention alone is self-documenting and indentifies it as an index. For indexes that span multiple columns, concatenate the column names. "ProductsIdUC" indicates a unique, clustered index on the Id column of the Products table. OrderDetailsOrderIdCustomerIdNN" indicates a non-unique, non-clustered index on the OrderId and CustomerId columns in the OrderDetails table. Since this name is rather lengthy with both "OrderId" and "CustomerId" spelled out, they could be shortened to OrdId and CustId. However, notice that by using Pascal Case, thus not needing to use underscores, it is possible to keep the name of a complex index to about 30 characters.&lt;br /&gt;    &lt;br /&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 3b&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Prefixes and Suffixes&lt;/em&gt;) - Avoid putting a prefix like "idx" or "IDX_" before your indexes. This is not necessary due to the naming convention discussed in Rule 3a. A suffix of "_idx" or "IDX" is not necessary either for the same reason.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;a name="Constraints"&gt;&lt;font color="#a52a2a" size="4"&gt;4. CONSTRAINTS&lt;/font&gt;&lt;/a&gt;&lt;/strong&gt;&lt;br /&gt;Constraints are at the field/column level so the name of the field the constraint is on should be used in the name. The type of constraint (Check, Referential Integrity a.k.a Foreign Key, Primary Key, or Unique) should be noted also. Constraints are also unique to a particular table and field combination, so you should include the table name also to ensure unique constaint names across your set of database tables.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 4a&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Naming Convention&lt;/em&gt;) - The naming convention syntax for constraints looks like this:&lt;br /&gt;&lt;br /&gt;     {constraint type}{table name}_{field name}&lt;br /&gt;&lt;br /&gt;Examples:&lt;br /&gt;1. PkProducts_Id  - primary key constraint on the Id field of the Products table&lt;br /&gt;2. &lt;/font&gt;&lt;font face="Verdana"&gt;FkOrders_ProductId    - foreign key constraint on the ProductId field in the Orders table&lt;br /&gt;3. CkCustomers_AccountRepId - check constraint on the AccountRepId field in the Customers table&lt;br /&gt;&lt;br /&gt;The reason underscores are used here with Pascal Case notation is so that the table name and field name are clearly separated. Without the underscore, it would become easy to get confused about where the table name stops and the field name starts.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 4b&lt;/font&gt;&lt;/strong&gt;(&lt;em&gt;Prefixes&lt;/em&gt;) A two letter prefix gets applied to the constraint name depending on the type&lt;br /&gt;     Primary Key: Pk&lt;br /&gt;     Foreign Key: Fk&lt;br /&gt;     Check: Ck&lt;br /&gt;     Unique: Un&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;a name="Views"&gt;&lt;font color="#a52a2a" size="4"&gt;&lt;strong&gt;5. VIEWS&lt;/strong&gt;&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;Views follow many of the same rules that apply to naming tables. There are only two differences (Rules 5a and 5b). If your view combines entities with a join condition or where clause, be sure to combine the names of the entities that are joined in the name of your view. This is discussed in more depth in Rule 5b.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 5a&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Prefixes&lt;/em&gt;) - While it is pointless to prefix tables, it can be helpful for views. Prefixing your views with "Vw" or "View" is a helpful reminder that you're dealing with a view, and not a table. Whatever type of prefix you choose to apply, use at least 2 letters and not just "V" because a prefix should use more more than one letter or its meaning can be ambiguous. &lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 5b&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;View Types&lt;/em&gt;) - Some views are simply tabular representations of one or more tables with a filter applied or because of security procedures (users given permissions on views instead of the underlying table(s) in some cases). Some views are used to generate report data with more specific values in the WHERE clause. Naming your views should be different depending on the type or purpose of the view. For simple views that just join one or more tables with no selection criteria, combine the names of the tables joined. For example, joining the "Customers" and "StatesAndProvinces" table to create a view of Customers and their respective geographical data should be given a name like "VwCustomersStatesAndProvinces". For a view that is more like a report, a name like "VwDivisionSalesFor2004" might make more sense.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;a name="StoredProcedures"&gt;&lt;font color="#a52a2a" size="4"&gt;&lt;strong&gt;6. STORED PROCEDURES&lt;br /&gt;&lt;/strong&gt;&lt;/font&gt;&lt;/a&gt;Unlike a lot of the other database objects discussed here, stored procedures are not logically tied to any table or column. Typically though, stored procedures perform one of the CRUD (Create, Read, Update, and Delete) operations on a table, or another action of some kind. Since stored procedures always perform some type of operation, it makes sense to use a name that describes the operation they perform. Use a verb to describe the type of operation, followed by the table(s) the operations occur on.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 6a&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Prefixes or Suffixes&lt;/em&gt;) - The way you name your stored procedures depends on how you want to group them within a listing. If you'd like to group them by the type of CRUD operation they perform, then prefix the name with "Create", "Get", "Update" or "Delete". Using this kind of prefix will, for example, group all of your "Create" procedures together since they will all start with the Create prefix, like "CreateProductInfo" or "CreateOrder". If instead, you would like to have your procedures ordered by the table they perform a CRUD operation on, adding "Create, Get, Update, or Delete" as a suffix will do that for you. For example, "ProductInfoCreate" or "OrdersCreate". If your procedure returns a scalar value, or performs an operation like validation, you should not use a CRUD prefix or suffix. Instead use the verb and noun combination. For example, "ValidateLogin"&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 6b&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Grouping Prefixes&lt;/em&gt;) - If you have many stored procedures, you might want to consider using a grouping prefix that can be used to identify which parts of an application the stored procedure is used by. For example, a "Prl" prefix for Payroll related procedures or a "Hr" prefix for Human Resources related procedures can be helpful. This prefix would come before a CRUD prefix (See Rul 6a). &lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 6c&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Bad Prefixes&lt;/em&gt;) - Do not prefix your stored procedures with something that will cause the system to think it is a system procedure. For example, in SQL Server, if you start a procedure with "sp_", "xp_" or "dt_" it will cause SQL Server to check the master database for this procedure first, causing a performance hit. Spend a little time researching if any of the prefixes you are thinking of using are known by the system and avoid using them if they are.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;a name="Triggers"&gt;&lt;font color="#a52a2a" size="4"&gt;&lt;strong&gt;7. TRIGGERS&lt;/strong&gt;&lt;/font&gt;&lt;/a&gt;&lt;br /&gt;Triggers have many things in common with stored procedures. However, triggers are different than stored procedures in two important ways. First, triggers don't exist on their own. They are dependant upon a table. So it is wise to include the name of this table in the trigger name. Second, triggers can only execute when either an Insert, Update, or Delete happens on one or more of the records in the table. So it also makes sense to include the type of action that will cause the trigger to execute.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 7a&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Prefixes and Suffixes&lt;/em&gt;) - To distinguish triggers from other database objects, it is helpful to add "Trg" as a prefix or suffix. For example any of these combinations work: Trg_ProductsIns, ProductsInsTrg, Products_InsTrg, or InsProducts_Trg. As long as you include the table name, the operation that executes the trigger (Ins, Upd, or Del) and the "Trg" letters, it should be obvious to someone working with the database what kind of object it is. As with all conventions you use, pick one and remain consistent.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 7b&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Multiple Operations&lt;/em&gt;) - If a trigger handles more than one operation (both INSERT and UPDATE for example) then include both operation abbreviations in your name. For example, "Products_InsUpdTrg" or "TrgProducts_UpdDel"&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font face="Verdana"&gt;&lt;strong&gt;&lt;font color="#000080"&gt;Rule 7c&lt;/font&gt;&lt;/strong&gt; (&lt;em&gt;Multiple Triggers&lt;/em&gt;) - Some systems allow multiple triggers per operation per table. In this case, you should make sure the names of these triggers are easy to distinguish between. For example "Users_ValidateEmailAddress_InsTrg" and "Users_MakeActionEntries_InsTrg".&lt;/font&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/864116869953733620-8630218705539378096?l=narulaamitsk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://narulaamitsk.blogspot.com/feeds/8630218705539378096/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=864116869953733620&amp;postID=8630218705539378096' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/8630218705539378096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/8630218705539378096'/><link rel='alternate' type='text/html' href='http://narulaamitsk.blogspot.com/2009/05/database-naming-conventions.html' title='DataBase Naming Conventions'/><author><name>Amit Narula</name><uri>http://www.blogger.com/profile/03373886236261160868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_KIFo2nRsLTc/SfIq-GgjUkI/AAAAAAAACCo/bBDItRMEB6s/S220/DSCF1775.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-864116869953733620.post-871609579045066239</id><published>2009-05-22T14:16:00.000-07:00</published><updated>2009-07-05T00:47:35.729-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net-Interview'/><title type='text'>C#.Winform Interview questions</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;font style="font-weight: bold;"&gt;What base class do all Web Forms inherit from?&lt;/font&gt;&lt;br /&gt;System.Windows.Forms.Form&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;What is the difference between Debug.Write and Trace.Write? When should each be used?&lt;/font&gt;&lt;br /&gt;The Debug.Write call won’t be compiled when the DEBUGsymbol is not defined (when doing a release build). Trace.Write calls will be compiled. Debug.Write is for information you want only in debug builds, Trace.Write is for when you want it in release build as well.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;Difference between Anchor and Dock Properties?&lt;/font&gt;&lt;br /&gt;Dock Property-&gt;Gets or sets which edge of the parent container a control is docked to. A control can be docked to one edge of its parent container or can be docked to all edges and fill the parent container. For example, if you set this property to DockStyle.Left, the left edge of the&lt;br /&gt;control will be docked to the left edge of its parent control. Additionally, the docked edge of the control is resized to match that of its container&lt;br /&gt;control.&lt;br /&gt;Anchor Property-&gt;Gets or sets which edges of the control are anchored to the edges of its container. A control can be anchored to one or more edges of its parent container. Anchoring a control to its parent ensures that the anchored edges remain in the same position relative to the edges of the parent container when the parent container is resized.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;When would you use ErrorProvider control?&lt;/font&gt;&lt;br /&gt;ErrorProvider control is used in Windows Forms application. It is like Validation Control for ASP.NET pages. ErrorProvider control is used to provide validations in Windows forms and display user friendly messages to the user if the validation fails.&lt;br /&gt;E.g&lt;br /&gt;If we went to validate the textBox1 should be empty, then we can validate as below&lt;br /&gt;1). You need to place the errorprovide control on the form&lt;br /&gt;private void textBox1_Validating (object sender, System.ComponentModel.CancelEventArgs e)&lt;br /&gt;{&lt;br /&gt;ValidateName();&lt;br /&gt;}&lt;br /&gt;Private bool ValidateName()&lt;br /&gt;{&lt;br /&gt;bool bStatus = true;&lt;br /&gt;if (textBox1.Text == “”)&lt;br /&gt;{&lt;br /&gt;errorProvider1.SetError (textBox1,”Please enter your Name”);&lt;br /&gt;bStatus = false;&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;errorProvider1.SetError (textBox1,”");&lt;br /&gt;return bStatus;&lt;br /&gt;}&lt;br /&gt;it check the textBox1 is empty . If it is empty, then a message Please enter your name is displayed.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;Can you write a class without specifying namespace? Which namespace does it belong to by default?&lt;/font&gt;&lt;br /&gt;Yes, you can, and then the class belongs to global namespace which has no name. For commercial products, naturally, you wouldn’t want global namespace.&lt;br /&gt;&lt;br /&gt;You are designing a GUI application with windows and several widgets on it. The user then resizes the app window and sees a lot of grey space, while the widgets stay in place. What’s the problem?&lt;br /&gt;One should use anchoring for correct resizing. Otherwise the default property of a widget on a form is top-left, so it stays at the same location when resized.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;How can you save the desired properties of Windows Forms application?&lt;/font&gt;&lt;br /&gt;.config files in .NET are supported through the API to allow storing and retrieving information. They are nothing more than simple XML files, sort of like what .ini files were before for Win32 apps.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;So how do you retrieve the customized properties of a .NET application from XML .config file?&lt;/font&gt;&lt;br /&gt;Initialize an instance of AppSettingsReader class. Call the GetValue method of AppSettingsReader class, passing in the name of the property and the type expected. Assign the result to the appropriate variable.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;Can you automate this process?&lt;/font&gt;&lt;br /&gt;In Visual Studio yes, use Dynamic Properties for automatic .config creation, storage and retrieval.&lt;br /&gt;&lt;br /&gt;My progress bar freezes up and dialog window shows blank, when an intensive background process takes over.&lt;br /&gt;Yes, you should’ve multi-threaded your GUI, with taskbar and main form being one thread, and the background process being the other.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;What’s the safest way to deploy a Windows Forms app?&lt;/font&gt;&lt;br /&gt;Web deployment: the user always downloads the latest version of the code, the program runs within security sandbox, properly written app will not require additional security privileges.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;Why is it not a good idea to insert code into InitializeComponent method when working with Visual Studio?&lt;/font&gt;&lt;br /&gt;The designers will likely through it away, most of the code inside InitializeComponent is auto-generated.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;font style="font-weight: bold;"&gt;What’s the difference between WindowsDefaultLocation and WindowsDefaultBounds?&lt;/font&gt;&lt;br /&gt;&lt;/div&gt;WindowsDefaultLocation tells the form to start up at a location selected by OS, but with internally specified size. WindowsDefaultBounds delegates both size and starting position choices to the OS.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;font style="font-weight: bold;"&gt;What’s the difference between Move and LocationChanged? Resize and SizeChanged?&lt;/font&gt;&lt;br /&gt;&lt;/div&gt;Both methods do the same, Move and Resize are the names adopted from VB to ease migration to C#.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;How would you create a non-rectangular window, let’s say an ellipse?&lt;/font&gt;&lt;br /&gt;Create a rectangular form, set the TransparencyKey property to the same value as BackColor, which will effectively make the background of the form transparent. Then set the FormBorderStyle to FormBorderStyle.None, which will remove the contour and contents of the form.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;How do you create a separator in the Menu Designer?&lt;/font&gt;&lt;br /&gt;A hyphen ‘-’ would do it. Also, an ampersand ‘&amp;amp;\’ would underline the next letter.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;How’s anchoring different from docking?&lt;/font&gt;&lt;br /&gt;Anchoring treats the component as having the absolute size and adjusts its location relative to the parent form. Docking treats the component location as absolute and disregards the component size. So if a status bar must always be at the bottom no matter what, use docking. If a button should be on the top right, but change its position with the form being resized, use anchoring.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;How do you trigger the Paint event in System.Drawing?&lt;/font&gt;&lt;br /&gt;Invalidate the current form; the OS will take care of repainting. The Update method forces the repaint.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;With these events, why wouldn’t Microsoft combine Invalidate and Paint, so that you wouldn’t have to tell it to repaint, and then to force it to repaint?&lt;/font&gt;&lt;br /&gt;Painting is the slowest thing the OS does, so usually telling it to repaint, but not forcing it allows for the process to take place in the background.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;How can you assign an RGB color to a System.Drawing.Color object?&lt;/font&gt;&lt;br /&gt;Call the static method FromArgb of this class and pass it the RGB values.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;What class does Icon derive from?&lt;/font&gt;&lt;br /&gt;Isn’t it just a Bitmap with a wrapper name around it? No, Icon lives in System.Drawing namespace. It’s not a Bitmap by default, and is treated separately by .NET. However, you can use ToBitmap method to get a valid Bitmap object from a valid Icon object.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;Before in my VB app I would just load the icons from DLL. How can I load the icons provided by .NET dynamically?&lt;/font&gt;&lt;br /&gt;By using System.Drawing.SystemIcons class, for example System.Drawing.SystemIcons.Warning produces an Icon with a warning sign in it.&lt;br /&gt;&lt;br /&gt;&lt;font style="font-weight: bold;"&gt;When displaying fonts, what’s the difference between pixels, points and ems?&lt;/font&gt;&lt;br /&gt;A pixel is the lowest-resolution dot the computer monitor supports. Its size depends on user’s settings and monitor size. A point is always 1/72 of an inch. An em is the number of pixels that it takes to display the letter M.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/864116869953733620-871609579045066239?l=narulaamitsk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://narulaamitsk.blogspot.com/feeds/871609579045066239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=864116869953733620&amp;postID=871609579045066239' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/871609579045066239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/871609579045066239'/><link rel='alternate' type='text/html' href='http://narulaamitsk.blogspot.com/2009/05/cwinform-interview-questions.html' title='C#.Winform Interview questions'/><author><name>Amit Narula</name><uri>http://www.blogger.com/profile/03373886236261160868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_KIFo2nRsLTc/SfIq-GgjUkI/AAAAAAAACCo/bBDItRMEB6s/S220/DSCF1775.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-864116869953733620.post-1118509934824023876</id><published>2009-04-23T01:24:00.001-07:00</published><updated>2009-07-05T00:48:09.953-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.Net-Interview'/><title type='text'>ASP.Net 2.0 Interview questions.</title><content type='html'>How to use Masterpages and Contentpages in ASP.NET 2.0? What is a Masterpage? What is a ContentPage? How to setup master-content pages in ASP.NET 2.0?&lt;br /&gt;&lt;br /&gt;A Master Page is the mother of the page and the content page is the baby! There may be many babies of the mother. A master page may have plenty of content pages within it. There also may be a master page within a master page, which is called a nested master page. Nested Master Pages&lt;br /&gt;&lt;br /&gt;So whats a master page in ASP.NET 2.0? A Master Page is a page that contains markup and controls that are shared across multiple pages in your site. For example, if required that all pages should have the same header and footer banners or the common navigation menu, the Master page can be written once, and all the content pages can access the common master page. The content pages inherit the tags inside the master page.&lt;br /&gt;&lt;br /&gt;Next question is how to define a master page. The answer is...&lt;br /&gt;&lt;br /&gt;To define a Master Page, it may be written like a normal page. Master Pages can contain markup, controls, or code, or any combination of these tags. The Content pages are rendered in a master page control called as ContentPlaceHolder control. A ContentPlaceHolder defines a region of the master page rendering that can be exchanged with content from a page associated to the master. A ContentPlaceHolder can also contain default content, when in case the derive page does not need to override this content. Below is the markup of how to use a Contentplaceholder.&lt;br /&gt;&lt;br /&gt;&amp;lt asp:contentplaceholder id="ContentPlaceHolderInterviewQuestions" runat="server"&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt asp:contentplaceholder id="ContentPlaceHolderInterviewQuestions" runat="server"&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt h3&gt;Welcome to the .NET Interview Questions website!&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt /asp:contentplaceholder&gt; &lt;br /&gt;&lt;br /&gt;A master page has the extension .master, unlike a normal web form that has the extenstion .aspx. A page may derive from a Master Page by defining a MasterPageFile attribute on its Page directive. Below is the markup of a content page.&lt;br /&gt;&lt;br /&gt;&lt;%@ Page MasterPageFile="Masterpage.master" %&gt;&lt;br /&gt;&amp;lt asp:content id="Content1" contentplaceholderid="ContentPlaceHolderInterviewQuestions" runat="server"&gt;&lt;br /&gt;Here goes contents of ContentPlaceHolderInterviewQuestions &amp;lt /asp:content&gt;&lt;br /&gt;&amp;lt /asp:contentplaceholder&gt;&lt;br /&gt;&lt;br /&gt;So how does Content page access a master page? It is also possible for a Content Page to programmatically access a Master Page. A ContentPage may create a strongly-typed reference to the Master Page using the &lt;%@ MasterType %&gt; directive, which specifies the virtual path to the masterpage as below...&lt;br /&gt;&lt;br /&gt;&lt;%@ MasterType VirtualPath="Masterpage.master" %&gt;&lt;br /&gt;&lt;br /&gt;The Content Page may then reference the Master Page using the Master property of the Page class:&lt;br /&gt;&lt;br /&gt;Master.FooterText = "Some text on the footer of .NET Interview Questions page";&lt;br /&gt;Label lb1 = Master.FindControl("label2");&lt;br /&gt;&lt;br /&gt;As with the example above, FooterText is a public property exposed on the Master Page, whereas label2 is a server side control on the Master Page.&lt;br /&gt;&lt;br /&gt;Note that the FindControl method is a very useful and a very important method, that may be used for finding a control in a content page from a master page and vice versa. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/864116869953733620-1118509934824023876?l=narulaamitsk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://narulaamitsk.blogspot.com/feeds/1118509934824023876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=864116869953733620&amp;postID=1118509934824023876' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/1118509934824023876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/1118509934824023876'/><link rel='alternate' type='text/html' href='http://narulaamitsk.blogspot.com/2009/04/aspnet-20-interview-questions.html' title='ASP.Net 2.0 Interview questions.'/><author><name>Amit Narula</name><uri>http://www.blogger.com/profile/03373886236261160868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_KIFo2nRsLTc/SfIq-GgjUkI/AAAAAAAACCo/bBDItRMEB6s/S220/DSCF1775.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-864116869953733620.post-642323197432637596</id><published>2009-04-21T04:04:00.000-07:00</published><updated>2009-07-05T00:49:15.753-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#Interview'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net-Interview'/><title type='text'>C# Questions</title><content type='html'>C#.NET&lt;br /&gt;&lt;br /&gt;Question:-Can it is possible that pointer are also in C#?&lt;br /&gt;Answer:Can you believe C#  supports pointers but in a limited extent. We all know  pointer is variable that only holds the memory address of another type. But pointer are little different in C# these declared to hold the memory address of value types and arrays  also pointer types are not tracked by the default garbage collection mechanism. Pointers are not allowed to point to a reference type or even to a structure type which contains a reference type. Pointers only point to  unmanaged types which includes all basic data types, enum types, other pointer types and structs which contain only unmanaged types.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Question:-What's New features are added to C#3.0 over C#2.0 ?&lt;br /&gt;Answer:These are the major new enhancements expected in C# 3.0:-&lt;br /&gt;* Implicitly typed local variables&lt;br /&gt;* Anonymous types&lt;br /&gt;* Extension methods&lt;br /&gt;* Object and collection initializers&lt;br /&gt;* Lambda expressions&lt;br /&gt;* Query expressions&lt;br /&gt;* Expression Trees&lt;br /&gt;&lt;br /&gt;Question:-How we Implicitly Typed Local Variables in C# 3.0 ?&lt;br /&gt;Answer:In C# 3.0 we have new keyword called "var".Var helps us to declare a new variable, which is implicitly inferred from the expression whic is used to initialize the variable here is the syntax:-&lt;br /&gt;var i = 1;&lt;br /&gt;In last line we initializes a variable i to value 1 and gives its type integer.We strongly type "i" to an integer.It is not an object or a VB6 variant,and it is not carry the overhead of an object or a variant.The var keyword allows you to refer to instances of anonymous types (described in the next section) and yet the instances are statically typed. So, when you create instances of a class that contain an arbitrary set of data, you don't need to predefine a class to both hold that structure and be able to hold that data in a statically typed variable.&lt;br /&gt;&lt;br /&gt;Question:-What do you mean by Anonymous Types in C# 3.0 ?&lt;br /&gt;Answer:In C# 3.0 we have options to create an instance of a class without writing code for the class beforehand.And code is so simple :-&lt;br /&gt;new {book="dotnet", writer="pervej", ageofwriter=24}&lt;br /&gt;In behind C# 3.0 compiler would create a class that looks as follows:&lt;br /&gt;class __anonymous&lt;br /&gt;{&lt;br /&gt;private string _book="dotnet";&lt;br /&gt;private string _writer="pervej";&lt;br /&gt;private int _ageofwriter=24;&lt;br /&gt;public string book {get { return _book; } set { _book = value; }}&lt;br /&gt;public string writer {get { return _writer; } set { _writer = value; }}&lt;br /&gt;public int ageofwriter {get { return _ageofwriter; } set { _ageofwriter = value; }}&lt;br /&gt;}&lt;br /&gt;in c# 3.0 we declare the same sequence of names and types , the C# compiler be smart enough to create a single anonymous type for both instances for use they are exchanged because the types are really the same.&lt;br /&gt;we have class, but still need something to take an instance of the above class. here the "var" keyword comes in handy it helps to hold a statically typed instance of the above instance of the anonymous type. Here is simple syntax of an anonymous type:&lt;br /&gt;var interviewquestion = new {book="dotnet", writer="pervej", ageofwriter=24}&lt;br /&gt;&lt;br /&gt;Question:-What the relation between Static method in Interface ?&lt;br /&gt;Answer:Static methods are common in class. In object oriented , an interface is not technically a class, it is a type, but not a class so interfaces do not extend Object. Because interfaces are not classes, they cannot have static methods, because there is no actual class to attach to.We may call InterfaceName.class to get the Class Object corresponding to the interface, but the Class class specifically states that it represents classes and interfaces in a object oriented application. However, the interface itself is not treated as a class, and hence you cannot attach a static method.&lt;br /&gt;&lt;br /&gt;Question:-How to get last month date from code in C# ?&lt;br /&gt;Answer:DateTime LastMonthDate=DateTime.Now.AddMonths(-1);&lt;br /&gt;&lt;br /&gt;Question:-What is Generic class how it helps programmer ?&lt;br /&gt;Answer:Generic is new feature included in .NET it is essential in C# .Because today the projects are more complicated as past so programmer badly need touse better reuse and customize their existing component-based software. So get this high level of code reuse in other languages, programmers have a option that option is Generics .By Using Generics, we can create class templates that support any type.&lt;br /&gt;&lt;br /&gt;Question:-What is the use of USING in c# ?&lt;br /&gt;Answer:As we all knows that one of beauty of C# is that it will releases memory automatically and in .NET CLR do this work calling garbage collector realse object that are not needed. USING is also play some role in releasing memory its programmer to specify which object should release that using resources.When object is provided to Using statement it must provided a iDisposable interface.This interface contains Dispose method.&lt;br /&gt;&lt;br /&gt;Question:-What is Partial class ?&lt;br /&gt;Answer:Partial class can also be split into two or more classes. We can also say that a class be physically separated into other parts of the class but within the same namespace and also one more important thing the parts must use the partial keyword.And other classes should also have the same access modifier.When compile is done, all the partial classes will be treated as a single class. Let us list some advantages of having partial classes.&lt;br /&gt;• Allows a clean separation of business logic layer and the user interface.&lt;br /&gt;• The UI code can be hidden from the developer.&lt;br /&gt;• Makes the debugging easier..&lt;br /&gt;&lt;br /&gt;Question: what are the Hiding method in c# can it is possible to hide method without using Virtual Function?&lt;br /&gt;Answer: It is possible to hide the base class method with the derived class without using Virtual in base class and Override keyword in subclass.there are some condition where we have to redefine any method in derived class same name in base class now question arise how can we hide the method anwer is simple and logical we use the modifier NEW which tell the compiler that derived class method "hides the base class method. There are some example:&lt;br /&gt;Class baseclass&lt;br /&gt;{&lt;br /&gt;    Public void display()&lt;br /&gt;    {&lt;br /&gt;        console.writeline("base method");&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;class derived : baseclass&lt;br /&gt;{&lt;br /&gt;    public new void display()&lt;br /&gt;    {&lt;br /&gt;         console.writeline("dervied mthod");&lt;br /&gt;     }&lt;br /&gt;}&lt;br /&gt;class test&lt;br /&gt;{&lt;br /&gt;     public static void main()&lt;br /&gt;    {&lt;br /&gt;        derived d=new derivedclass();&lt;br /&gt;        d.display();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Question:-explain some of method of System.Array class ?&lt;br /&gt;Answer:-&lt;br /&gt;Clear():-Set ranges of value to empty.&lt;br /&gt;CopyTo():-Copies element source to desinations.&lt;br /&gt;GetLength()-:Display number of element in given array.&lt;br /&gt;GetValue():-Value of given index in array.&lt;br /&gt;Length():-To get length of array.&lt;br /&gt;SetValue():-Sets the value of given index in the array.&lt;br /&gt;Reverse() :-Reverse the element of Array.&lt;br /&gt;Sort():-Sort the element in array.&lt;br /&gt;&lt;br /&gt;Question: what do u mean by Array in C# ?&lt;br /&gt;Answer: Array is a group of same type of datatype variable that shared a common name .The ability to use a single name to represent a collections of item is an array.There are manily three types of array.&lt;br /&gt;*One-Dimensinal Array&lt;br /&gt;*Two-Dimensinal Array&lt;br /&gt;*Multi-Dimensinal Array&lt;br /&gt;There are three steps include to create a Array&lt;br /&gt;(1) Declare an array&lt;br /&gt;(2)Creating memory location&lt;br /&gt;(3)Putting values into the memory location&lt;br /&gt;Declare the Array:-int[] counter;(declare int array)&lt;br /&gt;Creating of Array:-arrayname=new type[size];&lt;br /&gt;putting values in array:-number=new int[5];&lt;br /&gt;number[0]=35;&lt;br /&gt;&lt;br /&gt;Question: What is difference between the System.Array.CopyTo() &amp; System.Array.Clone()?&lt;br /&gt;Answer: The Clone() method returns a new array object containing all the elements in the original array. The CopyTo() method copies the elements into another existing array. Both perform a shallow copy. A shallow copy means the contents (each element) contains references to the same object as the elements in the original array. A deep copy (which neither of these methods performs) would create a new instance of each element's object, resulting in a different, yet identacle object.&lt;br /&gt;&lt;br /&gt;Question: Is there an equivalent of exit() for quitting a C# .NET application ?&lt;br /&gt;Answer: Yes, you can use System.Environment.Exit(int exitCode) to exit the application or Application.Exit() if it’s a Windows Forms app.&lt;br /&gt;&lt;br /&gt;Question: Is there a way to force garbage collection ?&lt;br /&gt;Answer: Yes. Set all references to null and then call System.GC.Collect(). If you need to have some objects destructed, and System.GC.Collect() doesn’t seem to be doing it for you, you can force finalizers to be run by setting all the references to the object to null and then calling System.GC.RunFinalizers().&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Question: Is there regular expression (regex) support available to C# developers ?&lt;br /&gt;Answer: Yes, The .NET class libraries provide support for regular expressions. Look at the System.Text.RegularExpressions namespace.&lt;br /&gt;&lt;br /&gt;Question: Define diffrent format for date time ?&lt;br /&gt;Answer: DateTime dt = new DateTime(2008, 3, 9, 16, 5, 7, 123);&lt;br /&gt;String.Format("{0:y yy yyy yyyy}", dt); // "8 08 008 2008" year&lt;br /&gt;String.Format("{0:M MM MMM MMMM}", dt); // "3 03 Mar March" month&lt;br /&gt;String.Format("{0:d dd ddd dddd}", dt); // "9 09 Sun Sunday" day&lt;br /&gt;String.Format("{0:h hh H HH}", dt); // "4 04 16 16" hour 12/24&lt;br /&gt;String.Format("{0:m mm}", dt); // "5 05" minute&lt;br /&gt;String.Format("{0:s ss}", dt); // "7 07" second&lt;br /&gt;String.Format("{0:f ff fff ffff}", dt); // "1 12 123 1230" sec.fraction&lt;br /&gt;String.Format("{0:F FF FFF FFFF}", dt); // "1 12 123 123" without zeroes&lt;br /&gt;String.Format("{0:t tt}", dt); // "P PM" A.M. or P.M.&lt;br /&gt;String.Format("{0:z zz zzz}", dt); // "-6 -06 -06:00" time zone&lt;br /&gt;String.Format("{0:d/M/yyyy HH:mm:ss}", dt); // "9/3/2008 16:05:07" - english (en-US)&lt;br /&gt;String.Format("{0:d/M/yyyy HH:mm:ss}", dt); // "9.3.2008 16:05:07" - german (de-DE)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Question: What is the difference between a struct and a class in C# ?&lt;br /&gt;Answer: From language spec: The list of similarities between classes and structs is as follows. Longstructs can implement interfaces and can have the same kinds of members as classes. Structs differ from classes in several important ways; however, structs are value types rather than reference types, and inheritance is not supported for structs. Struct values are stored on the stack or in-line. Careful programmers can sometimes enhance performance through judicious use of structs. For example, the use of a struct rather than a class for a Point can make a large difference in the number of memory allocations performed at runtime. The program below creates and initializes an array of 100 points. With Point implemented as a class, 101 separate objects are instantiated-one for the array and one each for the 100 elements.&lt;br /&gt;&lt;br /&gt;Question: Why do I get a syntax error when trying to declare a variable called checked ?&lt;br /&gt;Answer: The word checked is a keyword in C#.&lt;br /&gt;&lt;br /&gt;Question: Are private class-level variables inherited ?&lt;br /&gt;Answer: Yes, but they are not accessible, so looking at it you can honestly say that they are not inherited. But they are.&lt;br /&gt;&lt;br /&gt;Question: What is the difference between the C#.NET and VB.NET ?&lt;br /&gt;Answer:&lt;br /&gt;&lt;br /&gt;VB.NET&lt;br /&gt;- It didn't have the XML Documentation.&lt;br /&gt;- It didn't have the Operator Overloading.&lt;br /&gt;- It didn't have the Pointer Type variables.&lt;br /&gt;&lt;br /&gt;C#.NET&lt;br /&gt;- It has XML Documentation, Operator Overloading and supports Pointer Variables using unsafe keyword.&lt;br /&gt;&lt;br /&gt;Question: Is it possible to inline assembly or IL in C# code ?&lt;br /&gt;Answer: No.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Question: What is the syntax for calling an overloaded constructor within a constructor (this() and constructorname() does not compile) ?&lt;br /&gt;Answer: The syntax for calling another constructor is as follows: class B { B(int i) { } } class C : B { C() : base(5) // call base constructor B(5) { } C(int i) : this() // call C() { } public static void Main() {} }.&lt;br /&gt;&lt;br /&gt;Question: Provide C# Keywords ?&lt;br /&gt;Answer: These are some most important keyword of c# :&lt;br /&gt;abstract  as  base  bool  break  byte  case  catch  char  checked  class  const  continue  decimal  default  delegate  do  double  else&lt;br /&gt;enum  event  explicit  extern  false  finally  fixed  float  for  foreach  goto  if  implicit  in  int  interface  internal  is  lock&lt;br /&gt;long  namespace  new  null  object  operator  out  override  params  private  protected  public  readonly  ref  return  sbyte  sealed  short  sizeof&lt;br /&gt;stackalloc  static  string  struct  switch  this  throw  true  try  typeof  uint  ulong  unchecked  unsafe  ushort  using  virtual  volatile  void&lt;br /&gt;while&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Question: What optimizations does the C# compiler perform when you use the /optimize+ compiler option ?&lt;br /&gt;Answer: The following is a response from a developer on the C# compiler team: We get rid of unused locals (i.e., locals that are never read, even if assigned). We get rid of unreachable code. We get rid of try-catch with an empty try. We get rid of try-finally with an empty try. We get rid of try-finally with an empty finally. We optimize branches over branches: gotoif A, lab1 goto lab2: lab1: turns into: gotoif !A, lab2 lab1: We optimize branches to ret, branches to next instruction, and branches to branches.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/864116869953733620-642323197432637596?l=narulaamitsk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://narulaamitsk.blogspot.com/feeds/642323197432637596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=864116869953733620&amp;postID=642323197432637596' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/642323197432637596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/642323197432637596'/><link rel='alternate' type='text/html' href='http://narulaamitsk.blogspot.com/2009/04/c-questions.html' title='C# Questions'/><author><name>Amit Narula</name><uri>http://www.blogger.com/profile/03373886236261160868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_KIFo2nRsLTc/SfIq-GgjUkI/AAAAAAAACCo/bBDItRMEB6s/S220/DSCF1775.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-864116869953733620.post-5506095461579096972</id><published>2009-04-21T02:01:00.001-07:00</published><updated>2009-07-05T00:49:38.269-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Interview Questions'/><title type='text'>SQL Server Questions</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;font style="font-family: times new roman;" color="#0000ff" size="2" face="MS Serif"&gt;How do you implement one-to-one,                 one-to-many and many-to-many relationships while                 designing tables?&lt;/font&gt;&lt;br /&gt;&lt;font style="font-family: times new roman;" color="#000000" size="2" face="MS Serif"&gt;One-to-One relationship can be         implemented as a single table and rarely as two tables         with primary and foreign key relationships.&lt;/font&gt;&lt;br /&gt;&lt;font style="font-family: times new roman;" color="#000000" size="2" face="MS Serif"&gt;         One-to-Many relationships are implemented by splitting         the data into two tables with primary key and foreign key         relationships.&lt;/font&gt;&lt;br /&gt;&lt;font style="font-family: times new roman;" color="#000000" size="2" face="MS Serif"&gt;         Many-to-Many relationships are implemented using a         junction table with the keys from both the tables forming         the composite primary key of the junction table.&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font style="font-family: times new roman;" color="#0000ff" size="2" face="MS Serif"&gt;What's the difference between a                 primary key and a unique key?&lt;/font&gt;&lt;br /&gt;&lt;font style="font-family: times new roman;" size="2" face="MS Serif"&gt;Both         primary key and unique enforce uniqueness of the column         on which they are defined. But by default primary key         creates a clustered index on the column, where are unique         creates a nonclustered index by default. Another major         difference is that, primary key doesn't allow NULLs, but         unique key allows one NULL only.&lt;/font&gt;&lt;br style="font-family: times new roman;"&gt;&lt;br style="font-family: times new roman;"&gt;&lt;font style="font-family: times new roman;" color="#0000ff" size="2" face="MS Serif"&gt;What are user defined datatypes                 and when you should go for them?&lt;/font&gt;&lt;br /&gt;&lt;font style="font-family: times new roman;" size="2" face="MS Serif"&gt;User         defined datatypes let you extend the base SQL Server         datatypes by providing a descriptive name, and format to         the database. Take for example, in your database, there         is a column called Flight_Num which appears in many         tables. In all these tables it should be varchar(8). In         this case you could create a user defined datatype called         Flight_num_type of varchar(8) and use it across all your         tables. &lt;/font&gt;&lt;br /&gt;&lt;font style="font-family: times new roman;" size="2" face="MS Serif"&gt;         &lt;/font&gt;&lt;br /&gt;&lt;font style="font-family: times new roman;" size="2" face="MS Serif"&gt;         See sp_addtype, sp_droptype in books online.&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font style="font-family: times new roman;" color="#0000ff" size="2" face="MS Serif"&gt;What is bit datatype and what's                 the information that can be stored inside a bit                 column?&lt;/font&gt;&lt;br /&gt;&lt;font style="font-family: times new roman;" size="2" face="MS Serif"&gt;Bit         datatype is used to store boolean information like 1 or 0         (true or false). Untill SQL Server 6.5 bit datatype could         hold either a 1 or 0 and there was no support for NULL.         But from SQL Server 7.0 onwards, bit datatype can         represent a third state, which is NULL. &lt;/font&gt;&lt;br /&gt;&lt;br style="font-family: times new roman;"&gt;&lt;font style="font-family: times new roman;" color="#0000ff" size="2" face="MS Serif"&gt;Define candidate key, alternate                 key, composite key.&lt;/font&gt;&lt;br style="font-family: times new roman;"&gt;&lt;font style="font-family: times new roman;" size="2" face="MS Serif"&gt;A         candidate key is one that can identify each row of a         table uniquely. Generally a candidate key becomes the         primary key of the table. If the table has more than one         candidate key, one of them will become the primary key,         and the rest are called alternate keys. &lt;/font&gt;&lt;br /&gt;&lt;font style="font-family: times new roman;" size="2" face="MS Serif"&gt;         &lt;/font&gt;&lt;br /&gt;&lt;font style="font-family: times new roman;" size="2" face="MS Serif"&gt;         A key formed by combining at least two or more columns is         called composite key. &lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font style="font-family: times new roman;" color="#0000ff" size="2" face="MS Serif"&gt;What are defaults? Is there a                 column to which a default can't be bound?&lt;/font&gt;                               &lt;/div&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font size="2"&gt;A default         is a value that will be used by a column, if no value is         supplied to that column while inserting data. IDENTITY columns and timestamp columns         can't have defaults bound to them. See CREATE DEFUALT in         books online.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;&lt;font style="font-family: times new roman;" color="#0000ff" size="2" face="MS Serif"&gt;What is a transaction and what                 are ACID properties?&lt;/font&gt;                               &lt;/div&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font color="#000000" size="2"&gt;A transaction is a logical unit of work         in which, all the steps must be performed or none. ACID         stands for Atomicity, Consistency, Isolation,         Durability. These are the properties of a transaction.         For more information and explanation of these properties,         see SQL Server books online or any RDBMS fundamentals         text book.&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font color="#0000ff" size="2"&gt;Explain different isolation                 levels&lt;/font&gt;                               &lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font color="#000000" size="2"&gt;An isolation level determines the degree         of isolation of data between concurrent transactions. The         default SQL Server isolation level is Read Committed.         Here are the other isolation levels (in the ascending         order of isolation): Read Uncommitted, Read Committed,         Repeatable Read, Serializable. See SQL Server books         online for an explanation of the isolation levels. Be         sure to read about SET TRANSACTION ISOLATION LEVEL, which         lets you customize the isolation level at the connection         level.&lt;/font&gt;&lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font color="#0000ff" size="2"&gt;CREATE INDEX myIndex ON                 myTable(myColumn)&lt;br /&gt;                What type of Index will get created after                 executing the above statement?&lt;/font&gt;                               &lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font color="#000000" size="2"&gt;Non-clustered index. Important thing to         note: By default a clustered index gets created on the         primary key, unless specified otherwise.&lt;/font&gt;&lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font color="#0000ff" size="2"&gt;What's the maximum size of a row?&lt;/font&gt;                               &lt;font color="#000000" size="2"&gt;&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font color="#000000" size="2"&gt;8060 bytes. Don't be surprised with         questions like 'what is the maximum number of columns per         table'. Check out SQL Server books online for the page         titled: "Maximum Capacity Specifications"&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;&lt;font style="font-family: times new roman;" color="#0000ff" size="2" face="MS Serif"&gt;What's the difference between                 DELETE TABLE and TRUNCATE TABLE commands?&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font style="font-family: times new roman;" size="2" face="MS Serif"&gt;DELETE         TABLE is a logged operation, so the deletion of each row         gets logged in the transaction log, which makes it slow.         TRUNCATE TABLE also deletes all the rows in a table, but         it won't log the deletion of each row, instead it logs         the deallocation of the data pages of the table, which         makes it faster. Of course, TRUNCATE TABLE can be rolled         back.&lt;/font&gt;&lt;br /&gt;&lt;em style="font-family: times new roman;"&gt;&lt;strong&gt;TRUNCATE&lt;/strong&gt;&lt;/em&gt;&lt;br style="font-family: times new roman;"&gt;&lt;span style="font-family: times new roman;"&gt; TRUNCATE is faster and uses fewer system and transaction log resources than DELETE.&lt;/span&gt;&lt;br style="font-family: times new roman;"&gt;&lt;span style="font-family: times new roman;"&gt; TRUNCATE removes the data by deallocating the data pages used to store the table’s data, and only the page deallocations are recorded in the transaction log.&lt;/span&gt;&lt;br style="font-family: times new roman;"&gt;&lt;span style="font-family: times new roman;"&gt; TRUNCATE removes all rows from a table, but the table structure and its columns, constraints, indexes and so on remain. The counter used by an identity for new rows is reset to the seed for the column.&lt;/span&gt;&lt;br style="font-family: times new roman;"&gt;&lt;span style="font-family: times new roman;"&gt; You cannot use TRUNCATE TABLE on a table referenced by a FOREIGN KEY constraint.&lt;/span&gt;&lt;br style="font-family: times new roman;"&gt;&lt;span style="font-family: times new roman;"&gt; Because TRUNCATE TABLE is not logged, it cannot activate a trigger.&lt;/span&gt;&lt;br style="font-family: times new roman;"&gt;&lt;span style="font-family: times new roman;"&gt; TRUNCATE can not be Rolled back using logs.&lt;/span&gt;&lt;br style="font-family: times new roman;"&gt;&lt;span style="font-family: times new roman;"&gt; TRUNCATE is DDL Command.&lt;/span&gt;&lt;br style="font-family: times new roman;"&gt;&lt;span style="font-family: times new roman;"&gt; TRUNCATE Resets identity of the table.&lt;/span&gt; &lt;/div&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;em&gt;&lt;strong&gt;DELETE&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;DELETE removes  rows one at a time and records an entry in the transaction log for each deleted row.&lt;br /&gt;If you want to retain the identity counter, use DELETE instead. If you want to remove table definition and its data, use the DROP TABLE statement.&lt;br /&gt;DELETE Can be used with or without a WHERE clause&lt;br /&gt;DELETE Activates Triggers.&lt;br /&gt;DELETE Can be Rolled back using logs.&lt;br /&gt;DELETE is DML Command.&lt;br /&gt;DELETE does not reset identity of the table.&lt;/p&gt;&lt;div style="text-align: justify;"&gt;&lt;br style="font-family: times new roman;"&gt;&lt;br /&gt;&lt;font style="font-family: times new roman;" color="#0000ff" size="2" face="MS Serif"&gt;What are constraints? Explain                 different types of constraints.&lt;/font&gt;                               &lt;/div&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font size="2"&gt;Constraints         enable the RDBMS enforce the integrity of the database         automatically, without needing you to create triggers,         rule or defaults.&lt;br /&gt;       &lt;br /&gt;        Types of constraints: NOT NULL, CHECK, UNIQUE, PRIMARY         KEY, FOREIGN KEY&lt;br /&gt;       &lt;br /&gt;        For an explanation of these constraints see books online         for the pages titled: "Constraints" and         "CREATE TABLE", "ALTER TABLE"&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;&lt;font style="font-family: times new roman;" color="#0000ff" size="2" face="MS Serif"&gt;Whar is an index? What are the                 types of indexes? How many clustered indexes can                 be created on a table? I create a separate index                 on each column of a table. what are the                 advantages and disadvantages of this approach?&lt;/font&gt;                               &lt;/div&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font size="2"&gt;Indexes in         SQL Server are similar to the indexes in books. They help         SQL Server retrieve the data quicker.&lt;br /&gt;       &lt;br /&gt;        Indexes are of two types. Clustered indexes and         non-clustered indexes. When you craete a clustered index         on a table, all the rows in the table are stored in the         order of the clustered index key. So, there can be only         one clustered index per table. Non-clustered indexes have         their own storage separate from the table data storage.         Non-clustered indexes are stored as B-tree structures (so         do clustered indexes), with the leaf level nodes having         the index key and it's row locater. The row located could         be the RID or the Clustered index key, depending up on         the absence or presence of clustered index on the table.&lt;br /&gt;       &lt;br /&gt;        If you create an index on each column of a table, it         improves the query performance, as the query optimizer         can choose from all the existing indexes to come up with         an efficient execution plan. At the same t ime, data         modification operations (such as INSERT, UPDATE, DELETE)         will become slow, as every time data changes in the         table, all the indexes need to be updated. Another         disadvantage is that, indexes need disk space, the more         indexes you have, more disk space is used.&lt;/font&gt;&lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font color="#0000ff" size="2"&gt;What are the steps you will take                 to improve performance of a poor performing                 query?&lt;/font&gt;                               &lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font color="#000000" size="2"&gt;This is a very open ended question and         there could be a lot of reasons behind the poor         performance of a query. But some general issues that you         could talk about would be: No indexes, table scans,         missing or out of date statistics, blocking, excess         recompilations of stored procedures, procedures and         triggers without SET NOCOUNT ON, poorly written query         with unnecessarily complicated joins, too much         normalization, excess usage of cursors and temporary         tables.&lt;br /&gt;       &lt;br /&gt;        Some of the tools/ways that help you troubleshooting         performance problems are: SET SHOWPLAN_ALL ON, SET         SHOWPLAN_TEXT ON, SET STATISTICS IO ON, SQL Server         Profiler, Windows NT /2000 Performance monitor, Graphical         execution plan in Query Analyzer.&lt;br /&gt;       &lt;br /&gt;        Download the white paper on performance tuning SQL Server         from Microsoft web site. Don't forget to check out &lt;/font&gt;&lt;a href="http://www.sql-server-performance.com/" target="_new"&gt;&lt;font color="#0000ff" size="2"&gt;sql-server-performance.com&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font color="#0000ff" size="2"&gt;What are cursors? Explain                 different types of cursors. What are the                 disadvantages of cursors? How can you avoid                 cursors?&lt;/font&gt;                               &lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font size="2"&gt;Cursors         allow row-by-row prcessing of the resultsets.&lt;br /&gt;       &lt;br /&gt;        Types of cursors: Static, Dynamic, Forward-only,         Keyset-driven. See books online for more information.&lt;br /&gt;       &lt;br /&gt;        Disadvantages of cursors: Each time you fetch a row from         the cursor, it results in a network roundtrip, where as a         normal SELECT query makes only one rowundtrip, however         large the resultset is. Cursors are also costly because         they require more resources and temporary storage         (results in more IO operations). Furthere, there are         restrictions on the SELECT statements that can be used         with some types of cursors.&lt;br /&gt;       &lt;br /&gt;        Most of the times, set based operations can be used         instead of cursors. Here is an example:&lt;br /&gt;       &lt;br /&gt;        If you have to give a flat hike to your employees using         the following criteria:&lt;br /&gt;       &lt;br /&gt;        Salary between 30000 and 40000 -- 5000 hike&lt;br /&gt;        Salary between 40000 and 55000 -- 7000 hike&lt;br /&gt;        Salary between 55000 and 65000 -- 9000 hike&lt;br /&gt;       &lt;br /&gt;        In this situation many developers tend to use a cursor,         determine each employee's salary and update his salary         according to the above formula. But the same can be         achieved by multiple update statements or can be combined         in a single UPDATE statement as shown below:&lt;br /&gt;       &lt;br /&gt;        &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;UPDATE         tbl_emp SET salary = &lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;         CASE WHEN salary BETWEEN 30000 AND 40000 THEN salary +         5000&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;         WHEN salary BETWEEN 40000 AND 55000 THEN salary + 7000&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;         WHEN salary BETWEEN 55000 AND 65000 THEN salary + 10000&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;         END&lt;/span&gt;&lt;br /&gt;       &lt;br /&gt;        &lt;/font&gt;&lt;font size="2"&gt;Another situation         in which developers tend to use cursors: You need to call         a stored procedure when a column in a particular row         meets certain condition. You don't have to use cursors         for this. This can be achieved using WHILE loop, as long         as there is a unique key to identify each row. For         examples of using WHILE loop for row by row processing,&lt;br /&gt;&lt;/font&gt;&lt;br /&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;&lt;font style="font-family: times new roman;" color="#0000ff" size="2" face="MS Serif"&gt;Write down the general syntax for                 a SELECT statements covering all the options.&lt;/font&gt;                               &lt;/div&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font size="2"&gt;Here's the         basic syntax: (Also checkout SELECT in books online for         advanced syntax).&lt;br /&gt;       &lt;br /&gt;        SELECT select_list&lt;br /&gt;        [INTO new_table_]&lt;br /&gt;        FROM table_source&lt;br /&gt;        [WHERE search_condition]&lt;br /&gt;        [GROUP BY group_by_expression]&lt;br /&gt;        [HAVING search_condition]&lt;br /&gt;        [ORDER BY order_expression [ASC | DESC] ]&lt;/font&gt;&lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font color="#0000ff" size="2"&gt;What is a join and explain                 different types of joins.&lt;/font&gt;                               &lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font size="2"&gt;Joins are         used in queries to explain how different tables are         related. Joins also let you select data from a table         depending upon data from another table.&lt;br /&gt;       &lt;br /&gt;        Types of joins: INNER JOINs, OUTER JOINs, CROSS JOINs.         OUTER JOINs are further classified as LEFT OUTER JOINS,         RIGHT OUTER JOINS and FULL OUTER JOINS.&lt;br /&gt;       &lt;br /&gt;        For more information see pages from books online titled:         "Join Fundamentals" and "Using         Joins".&lt;/font&gt;&lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font color="#0000ff" size="2"&gt;What are triggers? How many                 triggers you can have on a table? How to invoke a                 trigger on demand?&lt;/font&gt;                               &lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font size="2"&gt;Triggers         are special kind of stored procedures that get executed         automatically when an INSERT, UPDATE or DELETE operation         takes place on a table.&lt;br /&gt;       &lt;br /&gt;        In SQL Server 6.5 you could define only 3 triggers per         table, one for INSERT, one for UPDATE and one for DELETE.         From SQL Server 7.0 onwards, this restriction is gone,         and you could create multiple triggers per each action.         But in 7.0 there's no way to control the order in which         the triggers fire. In SQL Server 2000 you could specify         which trigger fires first or fires last using         sp_settriggerorder&lt;br /&gt;       &lt;br /&gt;        Triggers can't be invoked on demand. They get triggered         only when an associated action (INSERT, UPDATE, DELETE)         happens on the table on which they are defined.&lt;br /&gt;       &lt;br /&gt;        Triggers are generally used to implement business rules,         auditing. Triggers can also be used to extend the         referential integrity checks, but wherever possible, use         constraints for this purpose, instead of triggers, as         constraints are much faster.&lt;br /&gt;       &lt;br /&gt;        Till SQL Server 7.0, triggers fire only after the data         modification operation happens. So in a way, they are         called post triggers. But in SQL Server 2000 you could         create pre triggers also. Search SQL Server 2000 books         online for INSTEAD OF triggers.&lt;br /&gt;       &lt;br /&gt;        Also check out books online for 'inserted table',         'deleted table' and COLUMNS_UPDATED()&lt;/font&gt;&lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font color="#0000ff" size="2"&gt;What is a self join? Explain it                 with an example.&lt;/font&gt;                               &lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font size="2"&gt;Self join         is just like any other join, except that two instances of         the same table will be joined in the query. Here is an         example: Employees table which contains rows for normal         employees as well as managers. So, to find out the         managers of all the employees, you need a self join.&lt;br /&gt;        &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;&lt;br /&gt;        &lt;span style="color: rgb(204, 0, 0);"&gt;CREATE TABLE emp &lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;         (&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;         empid int,&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;         mgrid int,&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;         empname char(10)&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;         )&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;         &lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;         INSERT emp SELECT 1,2,'Vyas'&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;         INSERT emp SELECT 2,3,'Mohan'&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;         INSERT emp SELECT 3,NULL,'Shobha'&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;         INSERT emp SELECT 4,2,'Shridhar'&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;         INSERT emp SELECT 5,2,'Sourabh'&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;         &lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;         SELECT t1.empname [Employee], t2.empname [Manager]&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;         FROM emp t1, emp t2&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;         WHERE t1.mgrid = t2.empid&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;           &lt;/div&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font size="2"&gt;Here's an advanced query using a LEFT OUTER JOIN  that even returns the employees without managers (super bosses)&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;        &lt;font style="color: rgb(204, 0, 0);" color="blue" size="2"&gt;SELECT t1.empname [Employee], COALESCE(t2.empname, 'No manager') [Manager]&lt;br /&gt; FROM emp t1&lt;br /&gt; LEFT OUTER JOIN&lt;br /&gt; emp t2&lt;br /&gt; ON&lt;br /&gt; t1.mgrid = t2.empid&lt;/font&gt;&lt;br /&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font size="2"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;T-SQL Code to find out Nth highest number in a column&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font style="color: rgb(51, 51, 255);" size="2"&gt;Ever wondered how                 to find out the second highest salary from the                 employees table? Or how to find out the third                 oldest employee in the company? Here is a stored                 procedure which accepts the table name, column                 name, and nth number and displays the nth highest                 number from the given column.&lt;/font&gt;&lt;font size="2"&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;&lt;pre style="font-family: times new roman;"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;CREATE PROC nth &lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;(&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt; @table_name sysname,&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt; @column_name sysname,&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt; @nth int&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;)&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;AS&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;BEGIN&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(51, 0, 153);"&gt;--Purpose: To find out the nth highest number in a column. Eg: Second highest salary from the salaries table&lt;/span&gt;&lt;br style="color: rgb(51, 0, 153);"&gt;&lt;span style="color: rgb(51, 0, 153);"&gt;--Input parameters: Table name, Column name, and the nth position&lt;/span&gt;&lt;br style="color: rgb(51, 0, 153);"&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;SET @table_name = RTRIM(@table_name)&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;SET @column_name = RTRIM(@column_name)&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;DECLARE @exec_str CHAR(400)&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;IF (SELECT OBJECT_ID(@table_name,'U')) IS NULL&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;BEGIN&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt; RAISERROR('Invalid table name',18,1)&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt; RETURN -1&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;END&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;IF NOT EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @table_name AND COLUMN_NAME = @column_name)&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;BEGIN&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt; RAISERROR('Invalid column name',18,1)&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt; RETURN -1&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;END&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;IF @nth &lt;= 0&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;BEGIN&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt; RAISERROR('nth highest number should be greater than Zero',18,1)&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt; RETURN -1&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;END&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;SET @exec_str = 'SELECT MAX(' + @column_name + ') from ' + @table_name + ' WHERE ' + @column_name +&lt;br /&gt; ' NOT IN ( SELECT TOP ' + LTRIM(STR(@nth - 1)) + ' ' + @column_name + ' FROM ' + @table_name +&lt;br /&gt;' ORDER BY ' + @column_name + ' DESC )'&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;EXEC (@exec_str)&lt;/span&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;br style="color: rgb(204, 0, 0);"&gt;&lt;span style="color: rgb(204, 0, 0);"&gt;END&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font size="2"&gt;&lt;strong style="color: rgb(51, 51, 255);"&gt;What is the difference between a HAVING CLAUSE and a WHERE CLAUSE?&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style="text-align: justify;"&gt;&lt;font size="2"&gt;&lt;strong style="color: rgb(51, 51, 255);"&gt;&lt;/strong&gt;&lt;br /&gt;Specifies a search condition for a group or an aggregate. HAVING can be used only with the SELECT statement. HAVING is typically used in a GROUP BY clause. When GROUP BY is not used, HAVING behaves like a WHERE clause. Having Clause is basically used only with the GROUP BY function in a query. WHERE Clause is applied to each row before they are part of the GROUP BY function in a query. HAVING criteria is applied after the the grouping of rows has occurred.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font size="2"&gt;&lt;strong style="color: rgb(51, 51, 255);"&gt;What is sub-query? Explain properties of sub-query.&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style="text-align: justify;"&gt;&lt;font size="2"&gt;&lt;strong style="color: rgb(51, 51, 255);"&gt;&lt;/strong&gt;&lt;br /&gt;Sub-queries are often referred to as sub-selects, as they allow a SELECT statement to be executed arbitrarily within the body of another SQL statement. A sub-query is executed by enclosing it in a set of parentheses. Sub-queries are generally used to return a single row as an atomic value, though they may be used to compare values against multiple rows with the IN keyword. &lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font size="2"&gt;A subquery is a SELECT statement that is nested within another T-SQL statement. A subquery SELECT statement if executed independently of the T-SQL statement, in which it is nested, will return a result set. Meaning a subquery SELECT statement can standalone and is not depended on the statement in which it is nested. A subquery SELECT statement can return any number of values, and can be found in, the column list of a SELECT statement, a FROM, GROUP BY, HAVING, and/or ORDER BY clauses of a T-SQL statement. A Subquery can also be used as a parameter to a function call. Basically a subquery can be used anywhere an expression can be used.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font size="2"&gt;&lt;em&gt;&lt;strong&gt;Properties of Sub-Query&lt;/strong&gt;&lt;/em&gt;&lt;br /&gt;A subquery must be enclosed in the parenthesis.&lt;br /&gt;A subquery must be put in the right hand of the comparison operator, and&lt;br /&gt;A subquery cannot contain a ORDER-BY clause.&lt;br /&gt;A query can contain more than one sub-queries.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font size="2"&gt;&lt;strong style="color: rgb(51, 102, 255);"&gt;What are types of sub-queries?&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&lt;p style="text-align: justify;"&gt;&lt;font size="2"&gt;&lt;strong style="color: rgb(51, 102, 255);"&gt;&lt;/strong&gt;&lt;br /&gt;Single-row subquery, where the subquery returns only one row.&lt;br /&gt;Multiple-row subquery, where the subquery returns multiple rows,.and&lt;br /&gt;Multiple column subquery, where the subquery returns multiple columns.&lt;/font&gt;&lt;/p&gt;&lt;p style="text-align: justify;"&gt;&lt;font size="2"&gt;&lt;span style="font-weight: bold; color: rgb(51, 51, 255);"&gt;What is User Defined Functions?&lt;/span&gt;&lt;br /&gt;User-Defined Functions allow to define its own T-SQL functions that can accept 0 or more parameters and return a single scalar data value or a table data type.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font size="2"&gt;&lt;span style="font-weight: bold; color: rgb(51, 51, 255);"&gt;What kind of User-Defined Functions can be created?&lt;/span&gt;&lt;br /&gt;There are three types of User-Defined functions in SQL Server 2000 and they are Scalar, Inline Table-Valued and Multi-statement Table-valued.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font size="2"&gt;&lt;em&gt;&lt;span style="font-weight: bold;"&gt;Scalar User-Defined Function&lt;/span&gt;&lt;/em&gt;&lt;br /&gt;A Scalar user-defined function returns one of the scalar data types. Text, ntext, image and timestamp data types are not supported. These are the type of user-defined functions that most developers are used to in other programming languages. You pass in 0 to many parameters and you get a return value.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font size="2"&gt;&lt;em&gt;&lt;span style="font-weight: bold;"&gt;Inline Table-Value User-Defined Function&lt;/span&gt;&lt;/em&gt;&lt;br /&gt;An Inline Table-Value user-defined function returns a table data type and is an exceptional alternative to a view as the user-defined function can pass parameters into a T-SQL select command and in essence provide us with a parameterized, non-updateable view of the underlying tables.&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;&lt;font size="2"&gt;&lt;em&gt;&lt;span style="font-weight: bold;"&gt;Multi-statement Table-Value User-Defined Function&lt;/span&gt;&lt;/em&gt;&lt;br /&gt;A Multi-Statement Table-Value user-defined function returns a table and is also an exceptional alternative to a view as the function can support multiple T-SQL statements to build the final result where the view is limited to a single SELECT statement. Also, the ability to pass parameters into a T-SQL select command or a group of them gives us the capability to in essence create a parameterized, non-updateable view of the data in the underlying tables. Within the create function command you must define the table structure that is being returned. After creating this type of user-defined function, It can be used in the FROM clause of a T-SQL command unlike the behavior found when using a stored procedure which can also return record sets.&lt;/font&gt;&lt;/p&gt;&lt;p style="font-family: times new roman; text-align: justify;"&gt;&lt;font size="2"&gt;&lt;br /&gt;&lt;/font&gt;&lt;/p&gt;&lt;div style="text-align: justify;"&gt;&lt;br style="font-family: times new roman;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br style="font-family: times new roman;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/864116869953733620-5506095461579096972?l=narulaamitsk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://narulaamitsk.blogspot.com/feeds/5506095461579096972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=864116869953733620&amp;postID=5506095461579096972' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/5506095461579096972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/5506095461579096972'/><link rel='alternate' type='text/html' href='http://narulaamitsk.blogspot.com/2009/04/sql-server-questions.html' title='SQL Server Questions'/><author><name>Amit Narula</name><uri>http://www.blogger.com/profile/03373886236261160868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_KIFo2nRsLTc/SfIq-GgjUkI/AAAAAAAACCo/bBDItRMEB6s/S220/DSCF1775.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-864116869953733620.post-8718282158919421245</id><published>2009-04-20T22:52:00.000-07:00</published><updated>2009-04-20T23:29:46.824-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Multithreading'/><title type='text'>3.Data Races &amp; Locks</title><content type='html'>&lt;h1&gt;&lt;span style="font-size:130%;"&gt;&lt;a name="data.races"&gt;Data races&lt;/a&gt;&lt;/span&gt;&lt;/h1&gt;     &lt;p&gt;       Well, that's shown you how to create a new thread and start it.       For a very few cases, it really is as simple as that - just occasionally,       you end up with a thread which doesn't need access to any data other than its       own (the counters in this case). Far more commonly, however, you need threads       to access the same data, sooner or later - and that's where the problems start.       Let's take a very simple program to start with:     &lt;/p&gt; &lt;table class="code"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt; &lt;span class="ReferenceType"&gt;class&lt;/span&gt; Test&lt;br /&gt;{&lt;br /&gt;  &lt;span class="Modifier"&gt;static&lt;/span&gt; &lt;span class="ValueType"&gt;int&lt;/span&gt; count=0;&lt;br /&gt;&lt;br /&gt;  &lt;span class="Modifier"&gt;static&lt;/span&gt; &lt;span class="ValueType"&gt;void&lt;/span&gt; Main()&lt;br /&gt;  {&lt;br /&gt;      ThreadStart job = &lt;span class="Keyword"&gt;new&lt;/span&gt; ThreadStart(ThreadJob);&lt;br /&gt;      Thread thread = &lt;span class="Keyword"&gt;new&lt;/span&gt; Thread(job);&lt;br /&gt;      thread.Start();&lt;br /&gt;    &lt;br /&gt;      &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; i=0; i &lt; class="String"&gt;"Final count: {0}"&lt;/span&gt;, count);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span class="Modifier"&gt;static&lt;/span&gt; &lt;span class="ValueType"&gt;void&lt;/span&gt; ThreadJob()&lt;br /&gt;  {&lt;br /&gt;      &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; i=0; i &lt;&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;     &lt;p&gt;       This is very straightforward - each of the threads just increments the &lt;code&gt;count&lt;/code&gt;       variable, and then the main thread displays the final value of &lt;code&gt;count&lt;/code&gt; at the end.       The only really new thing here is the call in the main thread to &lt;code&gt;Thread.Join&lt;/code&gt;,       which basically pauses the main thread until the other thread has completed.     &lt;/p&gt;     &lt;p&gt;       So, the result should always be &lt;code&gt;Final count: 10&lt;/code&gt;, right? Well, no. In fact,       chances are that that &lt;i&gt;will&lt;/i&gt; be the result if you run the above code - but it isn't       guaranteed to be. There are two reasons for this - one fairly simple, and one much subtler.       We'll leave &lt;a href="http://www.yoda.arachsys.com/csharp/threads/volatility.shtml"&gt;the subtle one&lt;/a&gt; for the moment, and just consider the simple one.     &lt;/p&gt;     &lt;p&gt;       The statement &lt;code&gt;count++;&lt;/code&gt; actually does three things: it reads the current value       of &lt;code&gt;count&lt;/code&gt;, increments that number, and then writes the new value back to the       &lt;code&gt;count&lt;/code&gt; variable. Now, if one thread gets as far as reading the current value,       then the other thread takes over, does the whole increment operation, and then the first       thread gets control again, its idea of the value of &lt;code&gt;count&lt;/code&gt; is out of date - so       it will increment the &lt;i&gt;old&lt;/i&gt; value, and write that newly incremented (but wrong) value       back into the variable.     &lt;/p&gt;     &lt;p&gt;       The easiest way of showing this is by separating the three operations and introducing some       &lt;code&gt;Sleep&lt;/code&gt; calls into the code, just to make it more likely that the threads will       clash heads, as it were. Note that introducing &lt;code&gt;Sleep&lt;/code&gt; calls should never change        the correctness of a program, in terms of threading - any thread can go to sleep at any       time, basically. In other words, you can never rely on two operations both happening without       another thread doing stuff in between. I've also put some diagnostics in to make it clearer       what's happening. The "main" thread's activities appear on the left, while the "other" thread's       activities are on the right. Here's the code:     &lt;/p&gt; &lt;table class="code"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt; &lt;span class="ReferenceType"&gt;class&lt;/span&gt; Test&lt;br /&gt;{&lt;br /&gt;  &lt;span class="Modifier"&gt;static&lt;/span&gt; &lt;span class="ValueType"&gt;int&lt;/span&gt; count=0;&lt;br /&gt;&lt;br /&gt;  &lt;span class="Modifier"&gt;static&lt;/span&gt; &lt;span class="ValueType"&gt;void&lt;/span&gt; Main()&lt;br /&gt;  {&lt;br /&gt;      ThreadStart job = &lt;span class="Keyword"&gt;new&lt;/span&gt; ThreadStart(ThreadJob);&lt;br /&gt;      Thread thread = &lt;span class="Keyword"&gt;new&lt;/span&gt; Thread(job);&lt;br /&gt;      thread.Start();&lt;br /&gt;    &lt;br /&gt;      &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; i=0; i &lt; class="ValueType"&gt;int&lt;/span&gt; tmp = count;&lt;br /&gt;          Console.WriteLine (&lt;span class="String"&gt;"Read count={0}"&lt;/span&gt;, tmp);&lt;br /&gt;          Thread.Sleep(50);&lt;br /&gt;          tmp++;&lt;br /&gt;          Console.WriteLine (&lt;span class="String"&gt;"Incremented tmp to {0}"&lt;/span&gt;, tmp);&lt;br /&gt;          Thread.Sleep(20);&lt;br /&gt;          count = tmp;&lt;br /&gt;          Console.WriteLine (&lt;span class="String"&gt;"Written count={0}"&lt;/span&gt;, tmp);&lt;br /&gt;          Thread.Sleep(30);&lt;br /&gt;      }&lt;br /&gt;    &lt;br /&gt;      thread.Join();&lt;br /&gt;      Console.WriteLine (&lt;span class="String"&gt;"Final count: {0}"&lt;/span&gt;, count);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span class="Modifier"&gt;static&lt;/span&gt; &lt;span class="ValueType"&gt;void&lt;/span&gt; ThreadJob()&lt;br /&gt;  {&lt;br /&gt;      &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; i=0; i &lt; class="ValueType"&gt;int&lt;/span&gt; tmp = count;&lt;br /&gt;          Console.WriteLine (&lt;span class="String"&gt;"\t\t\t\tRead count={0}"&lt;/span&gt;, tmp);&lt;br /&gt;          Thread.Sleep(20);&lt;br /&gt;          tmp++;&lt;br /&gt;          Console.WriteLine (&lt;span class="String"&gt;"\t\t\t\tIncremented tmp to {0}"&lt;/span&gt;, tmp);&lt;br /&gt;          Thread.Sleep(10);&lt;br /&gt;          count = tmp;&lt;br /&gt;          Console.WriteLine (&lt;span class="String"&gt;"\t\t\t\tWritten count={0}"&lt;/span&gt;, tmp);&lt;br /&gt;          Thread.Sleep(40);&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;     &lt;p&gt;       ... and here's one set of results I saw ...     &lt;/p&gt; &lt;table class="results"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;Read count=0&lt;br /&gt;                              Read count=0&lt;br /&gt;                              Incremented tmp to 1&lt;br /&gt;                              Written count=1&lt;br /&gt;Incremented tmp to 1&lt;br /&gt;Written count=1&lt;br /&gt;                              Read count=1&lt;br /&gt;                              Incremented tmp to 2&lt;br /&gt;Read count=1&lt;br /&gt;                              Written count=2&lt;br /&gt;                              Read count=2&lt;br /&gt;Incremented tmp to 2&lt;br /&gt;                              Incremented tmp to 3&lt;br /&gt;Written count=2&lt;br /&gt;                              Written count=3&lt;br /&gt;Read count=3&lt;br /&gt;                              Read count=3&lt;br /&gt;Incremented tmp to 4&lt;br /&gt;                              Incremented tmp to 4&lt;br /&gt;                              Written count=4&lt;br /&gt;Written count=4&lt;br /&gt;                              Read count=4&lt;br /&gt;Read count=4&lt;br /&gt;                              Incremented tmp to 5&lt;br /&gt;                              Written count=5&lt;br /&gt;Incremented tmp to 5&lt;br /&gt;Written count=5&lt;br /&gt;Read count=5&lt;br /&gt;Incremented tmp to 6&lt;br /&gt;Written count=6&lt;br /&gt;Final count: 6&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;     &lt;p&gt;       Just looking at the first few lines shows exactly the nasty behaviour described before       the code: the main thread has read the value 0, the other thread has incremented        &lt;code&gt;count&lt;/code&gt; to 1, and then the main thread has incremented its "stale" value        from 0 to 1, and written that value to the variable. The same thing happens a few more        times, and the end result is that &lt;code&gt;count&lt;/code&gt; is 6, instead of 10.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Exclusive access - Monitor. Enter Exit and the lock statement&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;        &lt;h1&gt;&lt;span style="font-size:130%;"&gt;&lt;a name="lock"&gt;&lt;/a&gt;&lt;/span&gt;&lt;a name="lock"&gt;&lt;/a&gt;&lt;/h1&gt;        &lt;p&gt;       What we need to fix the problem above is to make sure that while one thread is in a read/increment/write       operation, no other threads can try to do the same thing. This is where monitors come in. Every object       in .NET has a (theoretical) &lt;i&gt;monitor&lt;/i&gt; associated with it. A thread can &lt;i&gt;enter&lt;/i&gt; (or &lt;i&gt;acquire&lt;/i&gt;)       a monitor only if no other thread has currently "got" it. Once a thread has acquired a monitor, it can acquire       it more times, or &lt;i&gt;exit&lt;/i&gt; (or &lt;i&gt;release&lt;/i&gt;) it. The monitor is only available to other threads again       once it has been exited as many times as it was entered. If a thread tries to acquire a monitor which is       owned by another thread, it will block until it is able to acquire it. (There may be more than one thread trying       to acquire the monitor, in which case when the current owner thread releases it for the last time, only one of       the threads will acquire it - the other one will have to wait for the new owner to release it too.)     &lt;/p&gt;       &lt;p&gt;        In our example, we want exclusive access to the &lt;code&gt;count&lt;/code&gt;        variable while we're performing the increment operation. First we need to        decide on an object to use for locking. I'll discuss this choice in more        detail &lt;a href="http://www.yoda.arachsys.com/csharp/threads/lockchoice.shtml"&gt;later&lt;/a&gt;, but for the moment we'll        introduce a new variable just for the purposes of locking:        &lt;code&gt;countLock&lt;/code&gt;. This is initialised to be a reference a new        object, and thereafter is never changed. It's important that it's not        changed - otherwise one thread would be locking on one object's monitor,        and another object might be locking on a different object's monitor, so        they could interfere with each other just like they did before.      &lt;/p&gt;       &lt;p&gt;       We then simply need to put each increment operation in a &lt;code&gt;Monitor.Enter&lt;/code&gt; and &lt;code&gt;Monitor.Exit&lt;/code&gt;       pair:     &lt;/p&gt;  &lt;table class="code"&gt; &lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt; &lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt; &lt;span class="ReferenceType"&gt;class&lt;/span&gt; Test&lt;br /&gt;{&lt;br /&gt;  &lt;span class="Modifier"&gt;static&lt;/span&gt; &lt;span class="ValueType"&gt;int&lt;/span&gt; count=0;&lt;br /&gt;  &lt;span class="Modifier"&gt;static&lt;/span&gt; &lt;span class="Modifier"&gt;readonly&lt;/span&gt; &lt;span class="ReferenceType"&gt;object&lt;/span&gt; countLock = &lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ReferenceType"&gt;object&lt;/span&gt;();&lt;br /&gt;&lt;br /&gt;  &lt;span class="Modifier"&gt;static&lt;/span&gt; &lt;span class="ValueType"&gt;void&lt;/span&gt; Main()&lt;br /&gt;  {&lt;br /&gt;      ThreadStart job = &lt;span class="Keyword"&gt;new&lt;/span&gt; ThreadStart(ThreadJob);&lt;br /&gt;      Thread thread = &lt;span class="Keyword"&gt;new&lt;/span&gt; Thread(job);&lt;br /&gt;      thread.Start();&lt;br /&gt;    &lt;br /&gt;      &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; i=0; i &lt; class="ValueType"&gt;int&lt;/span&gt; tmp = count;&lt;br /&gt;          Console.WriteLine (&lt;span class="String"&gt;"Read count={0}"&lt;/span&gt;, tmp);&lt;br /&gt;          Thread.Sleep(50);&lt;br /&gt;          tmp++;&lt;br /&gt;          Console.WriteLine (&lt;span class="String"&gt;"Incremented tmp to {0}"&lt;/span&gt;, tmp);&lt;br /&gt;          Thread.Sleep(20);&lt;br /&gt;          count = tmp;&lt;br /&gt;          Console.WriteLine (&lt;span class="String"&gt;"Written count={0}"&lt;/span&gt;, tmp);&lt;br /&gt;          Monitor.Exit(countLock);&lt;br /&gt;          Thread.Sleep(30);&lt;br /&gt;      }&lt;br /&gt;    &lt;br /&gt;      thread.Join();&lt;br /&gt;      Console.WriteLine (&lt;span class="String"&gt;"Final count: {0}"&lt;/span&gt;, count);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span class="Modifier"&gt;static&lt;/span&gt; &lt;span class="ValueType"&gt;void&lt;/span&gt; ThreadJob()&lt;br /&gt;  {&lt;br /&gt;      &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; i=0; i &lt; class="ValueType"&gt;int&lt;/span&gt; tmp = count;&lt;br /&gt;          Console.WriteLine (&lt;span class="String"&gt;"\t\t\t\tRead count={0}"&lt;/span&gt;, tmp);&lt;br /&gt;          Thread.Sleep(20);&lt;br /&gt;          tmp++;&lt;br /&gt;          Console.WriteLine (&lt;span class="String"&gt;"\t\t\t\tIncremented tmp to {0}"&lt;/span&gt;, tmp);&lt;br /&gt;          Thread.Sleep(10);&lt;br /&gt;          count = tmp;&lt;br /&gt;          Console.WriteLine (&lt;span class="String"&gt;"\t\t\t\tWritten count={0}"&lt;/span&gt;, tmp);&lt;br /&gt;          Monitor.Exit(countLock);&lt;br /&gt;          Thread.Sleep(40);&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt; &lt;/table&gt;       &lt;p&gt;The results look a lot better this time:&lt;/p&gt;  &lt;table class="results"&gt; &lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;Read count=0&lt;br /&gt;Incremented tmp to 1&lt;br /&gt;Written count=1&lt;br /&gt;                              Read count=1&lt;br /&gt;                              Incremented tmp to 2&lt;br /&gt;                              Written count=2&lt;br /&gt;Read count=2&lt;br /&gt;Incremented tmp to 3&lt;br /&gt;Written count=3&lt;br /&gt;                              Read count=3&lt;br /&gt;                              Incremented tmp to 4&lt;br /&gt;                              Written count=4&lt;br /&gt;Read count=4&lt;br /&gt;Incremented tmp to 5&lt;br /&gt;Written count=5&lt;br /&gt;                              Read count=5&lt;br /&gt;                              Incremented tmp to 6&lt;br /&gt;                              Written count=6&lt;br /&gt;Read count=6&lt;br /&gt;Incremented tmp to 7&lt;br /&gt;Written count=7&lt;br /&gt;                              Read count=7&lt;br /&gt;                              Incremented tmp to 8&lt;br /&gt;                              Written count=8&lt;br /&gt;Read count=8&lt;br /&gt;Incremented tmp to 9&lt;br /&gt;Written count=9&lt;br /&gt;                              Read count=9&lt;br /&gt;                              Incremented tmp to 10&lt;br /&gt;                              Written count=10&lt;br /&gt;Final count: 10&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt; &lt;/table&gt;       &lt;p&gt;       The fact that the increments were strictly alternating here is just due       to the sleeps - in a more normal system there could be two increments in one thread,       then three in another, etc. The important thing is that they would always be thread-safe:       each increment would be isolated from each other increment, with only one being processed        at a time.     &lt;/p&gt;       &lt;p&gt;       There's a chance - a tiny chance, but a chance nonetheless - that the code above would hang,        however. If part of the increment operation (one of the calls to &lt;code&gt;Console.WriteLine&lt;/code&gt;, for instance)       threw an exception, the thread would still own the monitor, so the other thread would never be able       to acquire it and move on. The obvious solution to this (if you're used to exception handling, at least) is to       put the call to &lt;code&gt;Monitor.Exit&lt;/code&gt; in a finally block, with everything after the call to        &lt;code&gt;Monitor.Enter&lt;/code&gt; in a try block. Just like the &lt;code&gt;using&lt;/code&gt; statement which puts a call to       &lt;code&gt;Dispose&lt;/code&gt; in a finally block automatically, C# provides the &lt;code&gt;lock&lt;/code&gt; statement to call       &lt;code&gt;Monitor.Enter&lt;/code&gt; and &lt;code&gt;Monitor.Exit&lt;/code&gt; with a try/finally block automatically. This makes       it much easier to get synchronization right, as you don't end up having to check for "balanced" calls to        &lt;code&gt;Enter&lt;/code&gt; and &lt;code&gt;Exit&lt;/code&gt; everywhere. It also makes sure that you don't try to release a monitor       you don't own: in the code we had above, if we changed the value of &lt;code&gt;countLock&lt;/code&gt; to be a reference to a        different object within the increment operation, we'd have failed to release the monitor we owned, and tried to        release a monitor we didn't own - which would (in theory) have caused a &lt;code&gt;SynchronizationLockException&lt;/code&gt;.        (In fact, the exception wouldn't have been thrown because there's a bug in the framework in version       1.0/1.1, but that's another story.)       The &lt;code&gt;lock&lt;/code&gt; statement automatically takes a copy of the reference you specify, and calls both        &lt;code&gt;Enter&lt;/code&gt; and &lt;code&gt;Exit&lt;/code&gt; with it. (In the example above, and everywhere else in this article,       variables used to hold locks are declared as read-only. I have yet to come across a good reason to change       what a particular piece of code locks on.)     &lt;/p&gt;       &lt;p&gt;       So, we can rewrite our previous code into the somewhat clearer and more robust code below:     &lt;/p&gt;  &lt;pre&gt;&lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt; &lt;span class="ReferenceType"&gt;class&lt;/span&gt; Test&lt;br /&gt;{&lt;br /&gt;  &lt;span class="Modifier"&gt;static&lt;/span&gt; &lt;span class="ValueType"&gt;int&lt;/span&gt; count=0;&lt;br /&gt;  &lt;span class="Modifier"&gt;static&lt;/span&gt; &lt;span class="Modifier"&gt;readonly&lt;/span&gt; &lt;span class="ReferenceType"&gt;object&lt;/span&gt; countLock = &lt;span class="Keyword"&gt;new&lt;/span&gt; &lt;span class="ReferenceType"&gt;object&lt;/span&gt;();&lt;br /&gt;&lt;br /&gt;  &lt;span class="Modifier"&gt;static&lt;/span&gt; &lt;span class="ValueType"&gt;void&lt;/span&gt; Main()&lt;br /&gt;  {&lt;br /&gt;      ThreadStart job = &lt;span class="Keyword"&gt;new&lt;/span&gt; ThreadStart(ThreadJob);&lt;br /&gt;      Thread thread = &lt;span class="Keyword"&gt;new&lt;/span&gt; Thread(job);&lt;br /&gt;      thread.Start();&lt;br /&gt;    &lt;br /&gt;      &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; i=0; i &lt; class="Statement"&gt;lock&lt;/span&gt; (countLock)&lt;br /&gt;          {&lt;br /&gt;              &lt;span class="ValueType"&gt;int&lt;/span&gt; tmp = count;&lt;br /&gt;              Console.WriteLine (&lt;span class="String"&gt;"Read count={0}"&lt;/span&gt;, tmp);&lt;br /&gt;              Thread.Sleep(50);&lt;br /&gt;              tmp++;&lt;br /&gt;              Console.WriteLine (&lt;span class="String"&gt;"Incremented tmp to {0}"&lt;/span&gt;, tmp);&lt;br /&gt;              Thread.Sleep(20);&lt;br /&gt;              count = tmp;&lt;br /&gt;              Console.WriteLine (&lt;span class="String"&gt;"Written count={0}"&lt;/span&gt;, tmp);&lt;br /&gt;          }&lt;br /&gt;          Thread.Sleep(30);&lt;br /&gt;      }&lt;br /&gt;    &lt;br /&gt;      thread.Join();&lt;br /&gt;      Console.WriteLine (&lt;span class="String"&gt;"Final count: {0}"&lt;/span&gt;, count);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span class="Modifier"&gt;static&lt;/span&gt; &lt;span class="ValueType"&gt;void&lt;/span&gt; ThreadJob()&lt;br /&gt;  {&lt;br /&gt;      &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; i=0; i &lt; class="Statement"&gt;lock&lt;/span&gt; (countLock)&lt;br /&gt;          {&lt;br /&gt;              &lt;span class="ValueType"&gt;int&lt;/span&gt; tmp = count;&lt;br /&gt;              Console.WriteLine (&lt;span class="String"&gt;"\t\t\t\tRead count={0}"&lt;/span&gt;, tmp);&lt;br /&gt;              Thread.Sleep(20);&lt;br /&gt;              tmp++;&lt;br /&gt;              Console.WriteLine (&lt;span class="String"&gt;"\t\t\t\tIncremented tmp to {0}"&lt;/span&gt;, tmp);&lt;br /&gt;              Thread.Sleep(10);&lt;br /&gt;              count = tmp;&lt;br /&gt;              Console.WriteLine (&lt;span class="String"&gt;"\t\t\t\tWritten count={0}"&lt;/span&gt;, tmp);&lt;br /&gt;          }&lt;br /&gt;          Thread.Sleep(40);&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/864116869953733620-8718282158919421245?l=narulaamitsk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://narulaamitsk.blogspot.com/feeds/8718282158919421245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=864116869953733620&amp;postID=8718282158919421245' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/8718282158919421245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/8718282158919421245'/><link rel='alternate' type='text/html' href='http://narulaamitsk.blogspot.com/2009/04/data-races-locks.html' title='3.Data Races &amp; Locks'/><author><name>Amit Narula</name><uri>http://www.blogger.com/profile/03373886236261160868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_KIFo2nRsLTc/SfIq-GgjUkI/AAAAAAAACCo/bBDItRMEB6s/S220/DSCF1775.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-864116869953733620.post-5300524817091603201</id><published>2009-04-20T22:51:00.001-07:00</published><updated>2009-04-20T23:25:22.970-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Multithreading'/><title type='text'>2. Passing Parameters to Threads</title><content type='html'>&lt;h1&gt;Passing Parameters to Threads&lt;/h1&gt;     &lt;p&gt;       Often when you start a thread, you want to give it some parameters -        usually some data it has to process, a queue to wait on, etc. The        &lt;code&gt;ThreadStart&lt;/code&gt; delegate doesn't take any parameters, so the        information has to be stored somewhere else if you are going to create a        new thread yourself. Typically, this means creating a new instance of a        class, and using that instance to store the information. Often the class        itself can contain the delegate used for starting the thread. For        example, we might have a program which needs to fetch the contents of        various URLs, and wants to do it in the background. You could write code        like this:     &lt;/p&gt; &lt;table class="code"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt; &lt;span class="ReferenceType"&gt;class&lt;/span&gt; UrlFetcher&lt;br /&gt;{&lt;br /&gt;   &lt;span class="ReferenceType"&gt;string&lt;/span&gt; url&lt;br /&gt;&lt;br /&gt;   &lt;span class="Modifier"&gt;public&lt;/span&gt; UrlFetcher (&lt;span class="ReferenceType"&gt;string&lt;/span&gt; url)&lt;br /&gt;   {&lt;br /&gt;       &lt;span class="Keyword"&gt;this&lt;/span&gt;.url = url;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   &lt;span class="Modifier"&gt;public&lt;/span&gt; &lt;span class="ValueType"&gt;void&lt;/span&gt; Fetch()&lt;br /&gt;   {&lt;br /&gt;       &lt;span class="InlineComment"&gt;// use url here&lt;/span&gt;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[... in a different class ...]&lt;br /&gt;            &lt;br /&gt;UrlFetcher fetcher = &lt;span class="Keyword"&gt;new&lt;/span&gt; UrlFetcher (myUrl);&lt;br /&gt;&lt;span class="Keyword"&gt;new&lt;/span&gt; Thread (&lt;span class="Keyword"&gt;new&lt;/span&gt; ThreadStart (fetcher.Fetch)).Start();&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;     &lt;p&gt;       In some cases, you actually just wish to call a method in some class (possibly       the currently executing class) with a specific parameter. In that case, you may       wish to use a nested class whose purpose is just to make this call - the state is       stored in the class, and the delegate used to start the thread just calls the       "real" method with the appropriate parameter. (Note that the object on which to       call the method in the first place will also be required as state unless the       method is static.)     &lt;/p&gt;     &lt;h2&gt;Using the thread pool instead&lt;/h2&gt;     &lt;p&gt;       One alternative to starting the thread using a &lt;code&gt;ThreadStart&lt;/code&gt; delegate       is to use the thread pool, either using &lt;code&gt;ThreadPool.QueueUserWorkItem&lt;/code&gt;       or by calling a delegate asynchronously. Both of these are covered later on in       a more &lt;a href="http://www.yoda.arachsys.com/csharp/threads/threadpool.shtml"&gt;detailed discussion of the thread pool&lt;/a&gt;, which        also contains examples. Note that calling a delegate asynchronously allows you       to specify multiple parameters, and those parameters are strongly typed.     &lt;/p&gt;     &lt;h2&gt;.NET 2.0 solution 1: anonymous methods (with and without the thread pool)&lt;/h2&gt;     &lt;p&gt;       One of the enhancements to C# in version 2.0 is anonymous methods.       These allow you to specify blocks of code as methods within other methods, and use those methods       as delegates. You can access variables (including local variables and parameters of the "outside" method)       within the anonymous method. For example, using an anonymous method to fetch a URL using a normal       &lt;code&gt;ThreadStart&lt;/code&gt; delegate (and using inference of delegate type too):     &lt;/p&gt; &lt;table class="code"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;ThreadStart starter = delegate { Fetch (myUrl); };&lt;br /&gt;&lt;span class="Keyword"&gt;new&lt;/span&gt; Thread(starter).Start();&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;     &lt;p&gt;       (This could have all been expressed within a single step, creating both the thread       and the delegate in the same line of code, but I believe the above is more readable.)       Here's similar code to use a &lt;code&gt;WaitCallback&lt;/code&gt; and queue the job in        &lt;code&gt;ThreadPool&lt;/code&gt;:     &lt;/p&gt; &lt;table class="code"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;WaitCallback callback = delegate (&lt;span class="ReferenceType"&gt;object&lt;/span&gt; state) { Fetch ((&lt;span class="ReferenceType"&gt;string&lt;/span&gt;)state); };&lt;br /&gt;ThreadPool.QueueUserWorkItem (callback, myUrl);&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;     &lt;p&gt;       Note the way that the state is declared.     &lt;/p&gt;     &lt;h2&gt;.NET 2.0 solution 2: &lt;code&gt;ParameterizedThreadStart&lt;/code&gt;&lt;/h2&gt;     &lt;p&gt;       In .NET 2.0, there is a new delegate, &lt;code&gt;ParameterizedThreadStart&lt;/code&gt;, which takes       a parameter of type &lt;code&gt;object&lt;/code&gt;. You can create a thread using an instance of       this delegate instead of just &lt;code&gt;ThreadStart&lt;/code&gt;, and a new overload to &lt;code&gt;Thread.Start&lt;/code&gt;       allows you to specify the value to be passed to the new thread. This is simple, but only accepts       a single parameter and isn't type-safe (just like the options when using thread pool threads).       The earlier code could then be rewritten as:     &lt;/p&gt;      &lt;pre&gt;[In some method or other]&lt;br /&gt;Thread t = &lt;span class="Keyword"&gt;new&lt;/span&gt; Thread (&lt;span class="Keyword"&gt;new&lt;/span&gt; ParameterizedThreadStart(FetchUrl));&lt;br /&gt;t.Start (myUrl);&lt;br /&gt;&lt;br /&gt;[And the actual method...]&lt;br /&gt;&lt;span class="Modifier"&gt;static&lt;/span&gt; &lt;span class="ValueType"&gt;void&lt;/span&gt; FetchUrl(&lt;span class="ReferenceType"&gt;object&lt;/span&gt; url)&lt;br /&gt;{&lt;br /&gt;   &lt;span class="InlineComment"&gt;// use url here, probably casting it to a known type before use&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/864116869953733620-5300524817091603201?l=narulaamitsk.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://narulaamitsk.blogspot.com/feeds/5300524817091603201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=864116869953733620&amp;postID=5300524817091603201' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/5300524817091603201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/864116869953733620/posts/default/5300524817091603201'/><link rel='alternate' type='text/html' href='http://narulaamitsk.blogspot.com/2009/04/2-passing-parameters-to-threads.html' title='2. Passing Parameters to Threads'/><author><name>Amit Narula</name><uri>http://www.blogger.com/profile/03373886236261160868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_KIFo2nRsLTc/SfIq-GgjUkI/AAAAAAAACCo/bBDItRMEB6s/S220/DSCF1775.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-864116869953733620.post-6672202787539330909</id><published>2009-04-20T04:59:00.000-07:00</published><updated>2009-04-20T23:25:22.974-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Multithreading'/><title type='text'>1. Introduction &amp; Basics</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;meta equiv="CONTENT-TYPE" content="text/html; charset=utf-8"&gt;&lt;title&gt;&lt;/title&gt;&lt;meta name="GENERATOR" content="OpenOffice.org 2.3  (Win32)"&gt;&lt;style type="text/css"&gt; 	&lt;!-- 		@page { size: 8.5in 11in; margin: 0.79in } 		P { margin-bottom: 0.08in } 		H1 { margin-bottom: 0.08in } 		H1.western { font-family: "Times New Roman", serif } 		H1.cjk { font-family: "Arial Unicode MS", sans-serif } 		H1.ctl { font-family: "Tahoma" } 		H2 { margin-bottom: 0.08in } 		H2.cjk { font-family: "Arial Unicode MS", sans-serif } 		H2.ctl { font-family: "Tahoma" } 	--&gt; 	&lt;/style&gt; &lt;/div&gt;&lt;br /&gt;&lt;h1&gt;Multi-threading in .NET: Introduction and suggestions&lt;/h1&gt;     &lt;p&gt;       One of the greatest understatements I've heard in a newsgroup was made by       Patricia Shanahan, in a Java newsgroup in 2001: "Multi-threaded programming        needs a little care." Multi-threading is probably one of the worst understood       aspects of programming, and these days almost all application programmers       need to understand it to some extent. This article acts as an introduction       to multi-threading and gives some hints and tips for how to do it safely.       Warning: I'm not an expert on the subject, and when the &lt;i&gt;real&lt;/i&gt; experts start        discussing it in detail, my head starts to spin somewhat. However, I've tried       to pay attention to those who know what they're doing, and hopefully the       contents of this article form at least part of a multi-threading "best practice".     &lt;/p&gt;     &lt;p&gt;       This article uses the C# type shorthands throughout - &lt;code&gt;int&lt;/code&gt;        for &lt;code&gt;Int32&lt;/code&gt; etc. I hope this makes it easier for C# developers        to read, and won't impede any other developers too much. It also only        talks about the C# ways of declaring variables to be volatile and locking        monitors. Developers using other languages can find the equivalents in their       own preferred environment, I'm sure.     &lt;/p&gt;          &lt;h1&gt;&lt;a name="intro"&gt;Introduction: What is multi-threading?&lt;/a&gt;&lt;/h1&gt;     &lt;p&gt;       The fact that you're reading this article in the first place means you probably       have at least some idea of what multi-threading is about: it's basically trying       to do more than one thing at a time within a process.     &lt;/p&gt;     &lt;p&gt;       So, what is a thread? A thread (or "thread of execution") is a sort of context       in which code is running. Any one thread follows program flow for       wherever it is in the code, in the obvious way. Before multi-threading,       effectively there was always one thread running for each process in an       operating system (and in many systems, there was only one process running anyway).       If you think of processes running in parallel in an operating system (e.g. a       browser downloading a file and a word processor allowing you to type, both "at       the same time"), then apply the same kind of thinking within a single process,       that's a reasonable way to visualise threading.     &lt;/p&gt;     &lt;p&gt;       Multi-threading can occur in a "real" sense, in that a multi-processor box may       have more than one processor executing instructions for a particular process at       a time, or it may be effectively "simulated" by multiple threads executing in        sequence: first some code for thread 1 is executed, then some code for thread 2,       then back to thread 1 etc. In this situation, if both thread 1 and thread 2 are        "compute bound" (all they're doing is computation, without waiting for any input        from the network, or file system, or user etc) then that won't actually speed        things up at all - in fact, it'll slow things down as the operating system has to       switch between threads, and the memory cache probably won't be as effective. However,       much of today's computing involves waiting for something to happen, and during that       time the processor can be doing something else. Intel's "Hyper-Threading" technology       which is on some of its more recent chips (bearing in mind that this article was       written in early 2004!) is a sort of hybrid between this "real" and "simulated"       threading - for more information, see        &lt;a href="http://www.intel.com/technology/hyperthread/"&gt;Intel's web page on the subject&lt;/a&gt;.     &lt;/p&gt;     &lt;h1&gt;&lt;a name="dotnet"&gt;How does multi-threading work in .NET?&lt;/a&gt;&lt;/h1&gt;     &lt;p&gt;       .NET has been designed from the start to support multi-threaded operation. There       are two main ways of multi-threading which .NET encourages: starting your own threads       with &lt;code&gt;ThreadStart&lt;/code&gt; delegates, and using the &lt;code&gt;ThreadPool&lt;/code&gt; class        either directly (using &lt;code&gt;ThreadPool.QueueUserWorkItem&lt;/code&gt;) or indirectly using       asynchronous methods (such as &lt;code&gt;Stream.BeginRead&lt;/code&gt;, or calling &lt;code&gt;BeginInvoke&lt;/code&gt;       on any delegate).     &lt;/p&gt;     &lt;p&gt;       In general, you should create a new thread "manually" for long-running tasks, and use the       thread pool only for brief jobs. The thread pool can only run so many jobs at once, and       some framework classes use it internally, so you don't want to block it with a lot of       tasks which need to block for other things. The examples in this article mostly use       manual thread creation. On the other hand, for short-running tasks, particularly those created       often, the thread pool is an excellent choice.     &lt;/p&gt;          &lt;h1&gt;&lt;a name="hello.world"&gt;Multi-threaded "Hello, world"&lt;/a&gt;&lt;/h1&gt;     &lt;p&gt;       Here is virtually the simplest threading example which actually shows something       happening:     &lt;/p&gt; &lt;table class="code"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;pre&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span class="Namespace"&gt;using&lt;/span&gt; System.Threading;&lt;br /&gt;&lt;br /&gt;&lt;span class="Modifier"&gt;public&lt;/span&gt; &lt;span class="ReferenceType"&gt;class&lt;/span&gt; Test&lt;br /&gt;{&lt;br /&gt;   &lt;span class="Modifier"&gt;static&lt;/span&gt; &lt;span class="ValueType"&gt;void&lt;/span&gt; Main()&lt;br /&gt;   {&lt;br /&gt;       ThreadStart job = &lt;span class="Keyword"&gt;new&lt;/span&gt; ThreadStart(ThreadJob);&lt;br /&gt;       Thread thread = &lt;span class="Keyword"&gt;new&lt;/span&gt; Thread(job);&lt;br /&gt;       thread.Start();&lt;br /&gt;      &lt;br /&gt;       &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; i=0; i &lt; 5; i++)&lt;br /&gt;       {&lt;br /&gt;           Console.WriteLine (&lt;span class="String"&gt;"Main thread: {0}"&lt;/span&gt;, i);&lt;br /&gt;           Thread.Sleep(1000);&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;  &lt;br /&gt;   &lt;span class="Modifier"&gt;static&lt;/span&gt; &lt;span class="ValueType"&gt;void&lt;/span&gt; ThreadJob()&lt;br /&gt;   {&lt;br /&gt;       &lt;span class="Statement"&gt;for&lt;/span&gt; (&lt;span class="ValueType"&gt;int&lt;/span&gt; i=0; i &lt; 10; i++)&lt;br /&gt;       {&lt;br /&gt;           Console.WriteLine (&lt;span class="String"&gt;"Other thread: {0}"&lt;/span&gt;, i);&lt;br /&gt;           Thread.Sleep(500);&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;     &lt;p&gt;       The code creates a new thread which runs the &lt;code&gt;ThreadJob&lt;/code&gt;        method, and starts it. That thread counts from 0 to 9 fairly fast (about        twice a second) while the main thread counts from 0 to 4 fairly slowl
