Friday, April 3, 2009
Job Loss ? 5 ways to recession proof your job.
It is the only and the best way to survive in worst time like this, so try to save your money and make 20% investment in short term investments so that in need you can liquidate you money quickly and rest 80% in long term investment be careful while investing because invest the big chunk in government sponsered schemes only eg. fixed diposits, mutual funds etc. otherwise in times like this value of you money will be much less then you have invested.
2. Break your credit card into multiple pieces, throw away your credit card in to dust bin and call your bank account customer care executive to close account, becouse credit card could make our life worst due to compoudedness of its interest.
3.Get away from Loans.
4. Buy all goods you use at a time for 1 month or year so that you can get discount.
5. Keep contant track and look at your budget.
Sunday, January 18, 2009
Encrypting and Decrypting connection strings in web.config
| ||||
| ||||
Microsoft Silverlight 2
From Microsoft website available to public
Microsoft Silverlight 2
Fact Sheet
October 2008
A New Way to See the Web
Over the past year Microsoft Silverlight has led the way for developers and designers to create compelling media experiences and rich Internet applications (RIAs) on the Web via an easy-to-use, quickly installed browser plug-in. With the release of Silverlight 2, Microsoft Corp. is delivering a wide range of new platform features and tooling options that enable designers and developers to better collaborate while creating more accessible, more discoverable and more secure end-user experiences.
Silverlight Momentum
Silverlight is one of the fastest-growing browser plug-ins in history, both in terms of customer adoption and consumer installations. In 2008, Silverlight powered the 2008 Beijing Olympic Games (http://www.microsoft.com/presspass/presskits/ms-olympics/default.mspx) and the Democratic National Convention (http://www.demconvention.com). In addition, companies such as CBS College Sports Network, Blockbuster Inc., AOL LLC, Hard Rock Cafe International Inc., HSN Inc. and Toyota Motor Corp. are using Silverlight to provide a unique and dynamic Web experience for their customers. Silverlight has also been widely adopted throughout the developer and designer community by means of the Silverlight Partner Initiative. With more than 150 companies in the program — 120 of which have joined in the past year — it is a vibrant ecosystem of agency, solution provider, content delivery network, independent software vendor and independent hardware vendor partners, which are delivering some of the most innovative Silverlight experiences on the Web today. Finally, consumer installations of the Silverlight plug-in are growing rapidly, with penetration in some countries approaching 50 percent.
Openness and Interoperability Support
Proving its commitment to openness and its support for interoperability, Microsoft is funding a project to integrate advanced Silverlight development capabilities into the open-source Eclipse integrated development environment (IDE), will publish the Silverlight Extensible Application Markup Language (XAML) Vocabulary Specification, and will make the Silverlight Control Pack available as open source software.
“We have been very pleased to have a project proposed to create Eclipse tools for Microsoft Silverlight,” said Mike Milinkovich, executive director of the Eclipse Foundation. “This proposed project will provide Eclipse developers with the ability to leverage Silverlight and Java Web Services when developing rich Internet applications. Having a strong endorsement from Microsoft for this project is a clear sign of their support for Eclipse and open source communities.”
· The Eclipse Tools for Microsoft Silverlight Project will integrate advanced Silverlight development capabilities into the Eclipse IDE and Eclipse Rich Client Platform. Developed by France-based IT solution provider Soyatec, the project is funded by Microsoft.
Increased interoperability. Eclipse will contain functionality that will help Java developers build Silverlight applications that work better with Java Web Services using representational state transfer (REST), Simple Object Access Protocol (SOAP), JavaScript Object Notation (JSON) and other standards.
Silverlight Project System and Silverlight Compiler. Eclipse will contain both an advanced project system for creating Silverlight applications and media experiences and a compiler for packaging Silverlight applications for deployment.
XAML editor and preview with code hinting and code completion. Eclipse will contain an advanced, standards-compliant XAML editor with code hinting and code completion, which helps detect and correct coding errors.
Full compatibility with Microsoft’s development and design tools. The XAML and Silverlight projects created by Eclipse will be fully supported by both Microsoft Visual Studio and Microsoft Expression Studio tools.
Results. See the picture below for a glimpse of a Silverlight application being created in Eclipse.
Availability. A preview of the bits was posted today at http://www.eclipse4sl.org under the Eclipse Public License Version 1.0. Customers can use the SourceForge project site to submit bugs and feedback or contribute to the project. The release candidate is scheduled to be available free for download by spring 2009.
Road map. Although the first version of the Eclipse Tools for Microsoft Silverlight will be optimized for the Windows version of Eclipse, the project plans to offer full support for the Mac and Linux versions of Eclipse in a later release.
· By publishing the Silverlight XAML Vocabulary Specification under the Open Specification Promise, Microsoft will better enable ISVs to read and write XAML for use in Silverlight projects in other design and development software applications, thus accelerating the creation of a robust authoring and server ecosystem for Silverlight. This documentation release complements Microsoft’s existing published specifications of the XAML object mapping rules and XAML vocabulary for Windows Presentation Foundation (WPF).
· By making the Silverlight Control Pack available as open-source software, which is built on CodePlex and released under the Open Source Initiative-approved Microsoft Public License (MS-PL), Microsoft is helping developers easily customize and ship their own expanded controls, augmenting the powerful built-in control set that already ships in Silverlight.
Featured controls in the Control Pack. DockPanel, WrapPanel, ViewBox, Label, HeaderedContentControl, Expander, TreeView, NumericUpDown, AutoComplete and Accordion are available.
Advanced skinning support. The Silverlight Control Pack will provide additional control skins and templates to customize the look and feel of both the core Silverlight and Control Pack controls.
Learning opportunity. Developers can learn how to create their own advanced Silverlight controls by using high-quality Microsoft source code as a starting point.
· Growing tooling support from partner ecosystem. Tool support for building Silverlight-enabled applications continues to grow, with partners such as Captaris Inc., Telerik Inc., ComponentOne LLC, Infragistics, Software FX Inc., Intersoft Solutions Corp., Developer Express Inc., K2, Gizmox and RemObjects Software LLC providing products ranging from forms layout and rich interactive components to workflow, programming languages and business intelligence.
“Microsoft is thrilled to see the momentum building around tooling support from our partners,” said Scott Guthrie, corporate vice president of the .NET Developer Division at Microsoft. “The breadth of these partner offerings enables Silverlight developers to build evermore sophisticated and capable applications, further broadening the appeal of Silverlight for use in a wide range of scenarios.”
New Features in Silverlight 2
Highlights of new features of Silverlight — which are fully supported by Expression Blend 2 SP1 and Microsoft Visual Studio 2008 SP1 — include these:
· Expanded .NET Framework language support. Unlike other runtimes, Silverlight 2 supports a variety of programming languages, including Visual Basic, C#, Managed JavaScript, IronPython and IronRuby, making it easier for developers already familiar with one of these languages to repurpose their existing skills.
Cutting-edge RIA development. With Silverlight 2, developers do not have to pay the “productivity tax” of converting their existing code to JavaScript to run inside the client. With support for languages such as Ruby and Python, Silverlight 2 enables developers to be on the cutting edge of RIA development, creating Asynchronous Ruby and XML (ARAX) and Asynchronous Python and XML (APAX) applications.
· A rich base class library. A compatible subset of the full .NET Framework gives developers the most comprehensive RIA runtime on the Web today, with unparalleled data access capabilities, local data caching and local data storage, superior input-output (IO) performance, and better threading. By leveraging the rich base class library of the .NET Framework, developers can minimize the amount of additional code they have to write for their projects.
Building better AJAX applications. Silverlight 2 includes APIs that enable the creation of better asynchronous JavaScript and XML (AJAX) applications, with improved HTML DOM/JavaScript integration with .NET code and with better data access through Language-Integrated Query (LINQ) and LINQ to XML library support.
· Powerful built-in rich controls allow developers and designers to quickly build applications through a rich set of built-in controls such as DataGrid, ListBox, Slider, ScrollViewer and Calendar. With the rich controls built into Silverlight 2, developers don’t have to start from scratch when building the controls for their rich Internet applications.
· Advanced styling and templating support gives designers and developers complete control over the look and feel of an application to ensure the custom brand experience for their rich Internet application meets their exacting requirements.
· Rich UI Library. Silverlight 2’s UI Library, a compatible subset of the WPF user interface framework featured in the full .NET Framework, makes building rich Web applications easier. The powerful graphics and animation engine enables developers to reuse skills, code and content to build rich applications for the browser that can be rapidly ported to the desktop and devices.
Better support for higher-level UI capabilities. The UI Framework in Silverlight contains support for higher-level UI capabilities such as layout management, data-binding, styles and template skinning.
· Comprehensive networking support enables Silverlight users to leverage the power of the .NET Framework’s Windows Communication Foundation and directly access resources on the Web by supporting cross-domain network access.
Out-of-the-box support for calling REST, WS*/SOAP, POX, RSS and standard HTTP services enables users to create Web 2.0-style applications that easily integrate with existing heterogeneous back-end systems.
· Advanced content protection features, now including Silverlight digital rights management (DRM), Powered by PlayReady. Silverlight DRM builds on Microsoft’s extensive expertise in developing DRM technologies, delivering robust protection for key Silverlight scenarios including live streaming, on-demand streaming and progressive downloads for connected experiences.
· Improved server scalability and expanded advertiser support. The combination of Silverlight 2 and Windows Server 2008 offers streaming video professionals industry-leading scalability and cutting-edge progressive download features. In addition, Silverlight offers superior search engine optimization capabilities and advanced in-stream advertising support through companies such as DoubleClick Inc. and EyeWonder Inc.
· Unparalleled interactivity with high-resolution content through Deep Zoom technology. The new Deep Zoom technology in Silverlight allows users to see images on the Web as never before. The smooth, in-place zooming and panning that Deep Zoom allows is a true advancement and raises the bar on what image viewing should be. It is also now possible through this feature to make super-high-resolution images easily consumable on the Web. Even better, Deep Zoom is designed in a way that will reduce Web hosting and bandwidth costs by sending to the browser exactly the right size and resolution image for the current display area.
Truncate and Delete
Truncate table also deletes all the rows in a table, but it won't log the deletion of each row, instead it logs the de-allocation of the data pages of the table, which makes it faster. Of course, truncate table cannot be rolled back.
Truncate table is functionally identical to delete statement with no where clause both remove all rows in the table. But truncate table is faster and uses fewer system and transaction log resources than delete.
Truncate table removes all rows from a table, but the table structure and its columns, constraints, indexes etc. remains as it is.
In truncate table the counter used by an identity column for new rows is reset to the seed for the column.
If you want to retain the identity counter, use delete statement instead.
If you want to remove table definition and its data, use the drop table statement.
You cannot use truncate table on a table referenced by a foreign key constraint; instead, use delete statement without a where clause. Because truncate table is not logged, it cannot activate a trigger.
Sunday, August 10, 2008
New DataSet Features in ADO.NET 2.0
Download the DataSetSamples.exe sample code associated with the article.
Contents
Introduction
Raw Performance
The DataTable – More Independent Than Before
Stream to Cache, Cache to Stream
Conclusion
Introduction
In the upcoming release of ADO.NET, ADO.NET 2.0, there are many new and improved features that affect many different .NET Framework classes and application development scenarios. This article discusses on the changes and enhancement to the core disconnected mode ADO.NET Framework classes—the DataSet and associated classes such as DataSet, DataTable, and DataView.
This article is actually the first of two articles on the DataSet and associated classes in ADO.NET 2.0. Here we will focus on the classes in the .NET Framework. In the subsequent article, we will focus on developing with these and related classes from within the Visual Studio 2005 development environment. Visual Studio 2005 offers several designers and tools that offer tremendous flexibility and productivity for developing the data-centric aspects of your application. As a result, each article will have a different "feel". This article is mainly an overview of new functionality, accompanied by explanations and code samples. In the next article, the focus is more on the development process, as we see how to develop a working application.
As I mentioned above, this article only covers a small slice of the new features of ADO.NET 2.0. An overview of some of the other features can be found in ADO.NET 2.0 Feature Matrix. More in depth information on some of the topics mentioned there can be found these articles:
- Asynchronous Command Execution in ADO.NET 2.0
- Generic Coding with the ADO.NET 2.0 Base Classes and Factories
- Schemas in ADO.NET 2.0
Unless noted otherwise, the contents of this article are based on the Beta 1 release of Visual Studio 2005. The code samples use the Northwind database that comes as a sample database with SQL Server 2000.
Raw Performance
Software developers are always concerned with performance. Sometimes they get over-concerned and make their code jump through hoops to just trim a little execution time, in places where it ultimately isn't significant—but that is a subject for another article. When it comes to ADO.NET 1.x DataSets, particularly those containing a large amount of data, the performance concerns expressed by developers are indeed justified. Large DataSets are slow—in two different contexts. The first time the sluggish performance is felt is when loading a DataSet (actually, a DataTable) with a large number of rows. As the number of rows in a DataTable increases, the time to load a new row increases almost proportionally to the number of rows in the DataTable. The other time the performance hit is felt is when serializing and remoting a large DataSet. A key feature of the DataSet is the fact that it automatically knows how to serialize itself, especially when we want to pass it between application tiers. However, a close look reveals that this serialization is quite verbose, consuming much memory and network bandwidth. Both of these performance bottlenecks are addressed in ADO.NET 2.0.
New Indexing Engine
The indexing engine for the DataTable has been completely rewritten in ADO.NET 2.0 and scales much better for large datasets. This results in faster basic inserts, updates, and deletes, and therefore faster Fill and Merge operations. While benchmarks and quantifying performance gains is always an application-specific and often risky affair, these improvements clearly provide more than an order of magnitude improvement in loading a DataTable with a million rows. But don't take my word for it, check it out yourself, with the following simple example. Add the following code as the click event handler for a button on a Windows form:
Private Sub LoadButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LoadButton.Click
Dim ds As New DataSet Dim time1 As New Date Dim i As Integer Dim dr As DataRow ds.Tables.Add("BigTable") ds.Tables(0).Columns.Add("ID", Type.GetType("System.Int32")) ds.Tables(0).Columns("ID").Unique = True ds.Tables(0).Columns.Add("Value", Type.GetType("System.Int32")) ' Show status label WaitLabel.Visible = True Me.Cursor = Cursors.WaitCursor Me.Refresh() ' catch start time time1 = DateTime.Now() ' Yes, we are loading a million rows to a DataTable!'
' If you compile/run this with ADO.NET 1.1, you have time ' to make and enjoy a fresh pot of coffee... Dim rand As New Random Dim value As Integer For i = 1 To 1000000 Try value = rand.Next dr = ds.Tables(0).NewRow() dr("ID") = value dr("Value") = value ds.Tables(0).Rows.Add(dr) Catch ex As Exception ' if there are any duplicate values, an exception ' will be thrown since the ID column was specified ' to be unique End Try Next ' reset cursor and label WaitLabel.Visible = False Me.Cursor = Me.DefaultCursor' Show elapsed time, in seconds
MessageBox.Show("Elapsed Time: " & _DateDiff(DateInterval.Second, time1, DateTime.Now))
' verify number of rows in the table ' This number will probably be less that the number ' of loop iterations, since if the same random number ' comes up, it will/can not be added to the table MessageBox.Show("count = " & ds.Tables(0).Rows.Count) End Sub When I ran this code in my environment with ADO.NET 1.1 and Visual Studio 2003, the execution time was about 30 minutes. With ADO.NET 2.0 and Visual Studio 2005, I had an execution time of approximately 40-50 seconds! When I lowered the number of rows to only half a million, the 1.1 version took about 45 seconds and the 2.0 version took about 20 seconds. Your numbers will vary, but I think the point is clear.
In fact, this example is a very simple one, since it contains only one index, for the unique column. However, as the number of indices on the specified DataTable increases, such as by adding additional DataViews, UniqueKeys and ForeignKeys, the performance difference will be that much greater.
Note The reason the ID value in the sample code is being generated by a random number generator rather than just using the loop counter as the ID, is in order to better represent the real-world scenario. In real applications, accessing the elements of a DataTable for Inserts, Updates, and Deletes is rarely done sequentially. For each operation, the row specified by the unique key must first be located. When inserting and deleting rows, the table's indices must be updated. If we were to just load a million rows with sequentially key values into an empty table, the results would be extremely fast, but misleading.
Binary Serialization Option
The major performance improvement in loading a DataTable with a lot of data did not require us to make any change at all to our existing ADO.NET 1.x code. In order to benefit from improved performance when serializing the DataSet, we need to work a bit harder—we need to add a single line of code to set the new RemotingFormat property.
In ADO.NET 1.x, the DataSet serializes as XML, even when using the binary formatter. In ADO.NET 2.0, in addition to this behavior, we can also specify true binary serialization, by setting the RemotingFormat property to SerializationFormat.Binary rather than (the default) SerializationFormat.XML. Let us take a look at the different outputs resulting from these two different options.
In order to maintain backwards compatibility (about which the ADO.NET team was always concerned), the default value of XML serialization will give us the same behavior as in ADO.NET 1.x. The results of this serialization can be seen by running this code:
Private Sub XMLButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles XMLButton.Click
Dim ds As New DataSet Dim da As New SqlDataAdapter("select * from [order details]", _GetConnectionString())
da.Fill(ds) Dim bf As New BinaryFormatter Dim fs As New FileStream("..\xml.txt", FileMode.CreateNew) bf.Serialize(fs, ds) End SubPrivate Function GetConnectionString() As String
' To avoid hard-coding the connection string in your code, ' use the application settings Return MySettings.Value.NorthwindConnectionEnd Function
Note that this code is explicitly using the BinaryFormatter class, yet the output in file xml.txt, shown in Figure 1, is clearly XML. Also, in this case, the size of the file is 388 KB.
Let us now change the serialization format to binary by adding the line
ds.RemotingFormat = SerializationFormat.Binary
and save the data to a different file by modifying the filename in the FileStream constructor so that the code now looks like this:
Private Sub BinaryButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BinaryButton.Click
Dim ds As New DataSet Dim da As New SqlDataAdapter("select * from [order details]", _GetConnectionString())
da.Fill(ds) Dim bf As New BinaryFormatter Dim fs As New FileStream("..\binary.txt", FileMode.CreateNew) ds.RemotingFormat = SerializationFormat.Binary bf.Serialize(fs, ds) End Sub The output in file binary.txt is shown in Figure 2. Here we see that it is now in fact binary data, pretty unintelligible to the human reader. Moreover, the size of this file is only 59 KB—again, an order of magnitude reduction in the amount of data that needs to be transferred and the CPU, memory, and bandwidth resources required to process it. It should be pointed out that this improvement is relevant when using remoting and not when using Web Services, since Web Services by definition must be passing XML. This means that you will only be able to take advantage of this enhancement when both sides of the communication are .NET-based and not when communicating to non-.NET platforms.
More in-depth details about DataSet serialization process can be found in Binary Serialization of DataSets.
The DataTable – More Independent Than Before
When discussing ADO.NET 1.x and its object model for disconnected data access, the central object was the DataSet. Sure it contained other objects, such the DataTable, DataRelation, DataRow, etc., but the attention generally started and revolved around the DataSet. It is true that most .NET developers were aware and leveraged the fact that the DataTable was quite useful on its own, without being encapsulated inside a DataSet. However, there were some scenarios where we couldn't do what we wanted to do with a DataTable unless we first took it and forced it into a DataSet. The most glaring and often painful example of this is to read and write (load and save) XML data in to and out of the DataTable. In ADO.NET 1.x, we must first add the DataTable to DataSet, just so we could read or write XML, since the methods to do so are only available on the DataSet!
One of the objectives of ADO.NET 2.0 was to make the standalone DataTable class far more functional and useful than it is in ADO.NET 1.x. The DataTable now supports the basic methods for XML, just as the DataSet does. This includes the following methods:
- ReadXML
- ReadXMLSchema
- WriteXML
- WriteXMLSchema
The DataTable is independently serializable and can be used in both web service and remoting scenarios. In addition to now supporting the Merge method, the stand-alone DataTable also supports new ADO.NET 2.0 features added to the DataSet:
- RemotingFormat property (discussed previously)
- Load method (discussed later in this article)
- GetDataReader method (discussed later in this article)
Note On the topic of XML, it is worth noting that in ADO.NET 2.0 there is much enhanced XML support—what Microsoft likes to call greater "XML Fidelity". This takes the form of support for the SQL Server 2005 XML data type, extended XSD schema support, an improved XSD schema inference engine, and the elimination of two often troublesome limitations: (i) The DataSet and DataTable classes can now handle multiple in-line schemas and (ii) The DataSet now fully supports namespaces, so that a DataSet can contain multiple DataTables with the same name, but from different namespaces, i.e., tables with the same unqualified names, but with different qualified names. Also, a child table with the same name and namespace that is included in multiple relations can be nested in multiple parent tables.
Stream to Cache, Cache to Stream
Another one of the main enhancements for the DataSet and DataTable classes in ADO.NET 2.0 is the availability of mechanisms to consume a DataReader (loading data into DataTables) and to expose a DataReader over the contents of DataTables.
Sometimes we have/receive our data in the form of a DataReader, but really want to have it in the form of a cached DataTable. The new Load method allows us to take an existing DataReader and use it to fill a DataTable with its contents.
Sometimes we have/receive our data in a cached form (DataTable) and need to access it via a DataReader type interface. The new GetTableReader method allows us to take an existing DataTable and access it with a DataReader interface and semantics.
In the following sections, we'll take a look at these new methods.
The Load Method – Basic Use
The Load method is a new method that has been added to the DataSet and the DataTable in ADO.NET 2.0. It loads a DataTable with the contents of a DataReader object. It can actually load multiple tables at one time, if the DataReader contains multiple resultsets.
The basic use of the Load method is quite straightforward:
MyDataTable.Load (MyDataReader) A more complete illustration of its use is shown in this sample code:
Private Sub LoadButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LoadButton.Click
TryUsing connection As New SqlConnection(GetConnectionString())
Using command As New SqlCommand("SELECT * from customers", connection) connection.Open() Using dr As SqlDataReader = command.ExecuteReader() 'Fill table with data from DataReader Dim dt As New DataTable dt.Load(dr, LoadOption.OverwriteRow) ' Display the data DataGridView1.DataSource = dt End Using End Using End Using Catch ex As SqlException MessageBox.Show(ex.Message) Catch ex As InvalidOperationException MessageBox.Show(ex.Message) Catch ex As Exception ' You might want to pass these errors ' back out to the caller. MessageBox.Show(ex.Message) End Try End Sub The code above initializes connection and command objects and then executes the ExecuteReader method to fetch the data from the database. The results of the query are provided as a DataReader, which is then passed to the Load method of the DataTable to fill it with the returned data. Once the DataTable is filled with the data, it can be bound and displayed in the DataGridView. The significance of the OverwriteRow load option for the (optional) LoadOption parameter will be explained in the next section.
The Load Method – Why am I loading this data?
If all you are doing with your DataSet/DataTable and DataAdapter is filling the DataSet with data from the data source, modifying that data, and then at some later point pushing it back into the data source, that things general move pretty smoothly. A first complication occurs if you are utilizing optimistic concurrency and a concurrency violation is detected (someone else already changed one of the rows you are trying to change). In this case what you normally need to do to resolve the conflict is to resynchronize the DataSet with the data source, so that the original values for the rows match the current database values. This can be accomplished by merging a DataTable with the new values into the original table (in ADO.NET 1.x, the merge method is only available on the DataSet):
OriginalTable.Merge(NewTable, True)
By matching rows with the same primary key, records in the new table are merged with the records in the original table. Of key significance here is the second parameter, PreserveChanges. This specifies that the merge operation should only update the original values for each row, and not affect the current values for the row. This allows the developer to subsequently execute a DataAdapter.Update that will now succeed in updating the data source with the changes (current values), since the original values now match the current data source values. If PreserveChanges is left at its default value of false, the merge would override both the original and current values of the rows in the original DataTable and all of the changes that were made would be lost.
However, sometimes we want to update data in the data source, where the new values don't come from programmatically modifying the values. Perhaps we obtain updated values from another database or from an XML source. In this scenario, we want to update the current values of the rows in the DataTable, but not affect the original values for those rows. There is no easy way to do this in ADO.NET 1.x. It is for this reason that the ADO.NET 2.0 Load method accepts a parameter LoadOption that indicates how to combine the new incoming rows with the same (primary key) rows already in the DataTable.
The LoadOption allows us to explicitly specify what our intention is when loading the data (synchronization or aggregation) and how we therefore want to merge the new and existing rows. Figure 3 outlines the various scenarios:
![]()
Where:
- Primary Data Source—DataTable/DataSet synchronizes/updates with only one Primary Data Source. It will track changes to allow for synchronization with primary data sources.
- Secondary Data Source—DataTable/DataSet accepts incremental data feeds from one or more Secondary Data Sources. It is not responsible for tracking changes for the purpose of synchronization with secondary data sources.
The three cases shown in Figure 3 can be summarized as follows:
- Case 1—Initialize DataTable(s) from Primary Data Source. The user wants to initialize an empty DataTable (original values and current values) with values from primary data source and then later, after changes have been made to this data, propagate the changes back to the primary data source.
- Case 2—Preserve Changes and Re-Sync from Primary Data Source. The user wants to take the modified DataTable and re-synchronize its contents (original values only) with the primary data source while maintaining the changes made (current values)
- Case 3—Aggregate incremental data feeds from one or more Secondary Data Sources. The user wants to accept changes (current values) from one or more secondary data sources and then propagate these changes back to the primary data source.
The LoadOption enumeration has three values that respectively represent these three scenarios:
- OverwriteRow—Update the current and original versions of the row with the value of the incoming row.
- PreserveCurrentValues (default)—Update original version of the row with the value of the incoming row.
- UpdateCurrentValues—Update the current version of the row with the value of the incoming row.
Note These names will probably change post-Beta 1.
Table 1 below summarizes the load semantics. If the incoming row and existing row agree on primary key values, then the row is processed using its existing DataRowState, else use 'Not Present' section (the last row in the table).
Table 1. Summary of Load Semantics
| Existing DataRow State | UpdateCurrentValues | OverwriteRow | PreserveCurrentValues (Default) |
| Added | Current = Original = - -- State = | Current = Original = State = | Current = Original = State = |
| Modified | Current = Original = State = | Current = Original = State = | Current = Original = State = |
| Deleted | (Undo Delete) and Current = Original = State = <> | (Undo Delete) and Current = Original = State = | Current = Original = State = |
| Unchanged | Current = Original = If new value same as existing value then State = Else State = | Current = Original = State = | Current = Original = State = |
| Not Present | Current = Original = --- State = <> | Current = Original = State = | Current = Original = State = |
Example
In order to illustrate the behavior specified in Table 1, I offer a simple example.
Assume that both the existing DataRow and incoming row have 2 columns with matching names. The first column is the primary key and the second column contains a numeric value. The tables below show the contents of the second column in the data rows.
Table 2 represents the contents of a row in all 4 states before invoking Load. The incoming row's second column value is 3. Table 3 shows its contents after load.
Table 2. Row State Before Load
| Existing Row State | Version | Added | Modified | Deleted | Unchanged |
| | Current | 2 | 2 | - | 4 |
| | Original | - | 4 | 4 | 4 |
Incoming Row
| Incoming Row |
| 3 |
Table 3. Row State After Load
| | UpdateCurrentValues | OverwriteRow | PreserveCurrentValues |
| Added | Current = <3> Original = --- State = | Current = <3> Original = <3> State = | Current = <2> Original = <3> State = |
| Modified | Current = <3> Original = <4> State = | Current = <3> Original = <3> State = | Current = <2> Original = <3> State = |
| Deleted | Current = <3> Original = <4> State = | Current = <3> Original = <3> State = | Current = <2> Original = <3> State = |
| Unchanged | Current = <3> Original = <4> State = | Current = <3> Original = <3> State = | Current = <3> Original = <3> State = |
| Not Present | Current = <3> Original = --- State = | Current = <3> Original = <3> State = | Current = <3> Original = <3> State = |
Note You can see the beginnings of this concept already in ADO.NET 1.x. The default behavior of the DataAdapter's Fill method when loading data into a DataTable is to mark all the rows as Unchanged (This can be overridden by setting the AcceptChangesOnFill property to False). However, when using ReadXML to load data into a DataSet, the rows are marked as Added. The rationale for this (which was implemented based on customer feedback) is that this would allow loading new data from an XML source into a DataSet and then using the associated DataAdapter to update the primary data source. If the rows were marked as Unchanged when loaded from ReadXML, the DataAdapter.Update would not detect and changes and would not execute any commands against the data source.
In order to provide similar functionality, the FillLoadOptions property has been added to the DataAdapter in order to offer the same semantics and behavior as the Load method described here, while still preserving the same (by default) existing behavior of the Fill method.
Another feature (which doesn't exist) that developers always ask about in ADO.NET 1.x, is the ability to manually modify the state of DataRow. While the options offered by the Load method may address most scenarios, you may still want to have finer-grained control over the row state—you may have a need to modify the state of individual rows. To that end, ADO.NET 2.0 introduces two new methods on the DataRow class: SetAdded and SetModified. Before you ask about setting the state to Deleted, or Unchanged, let me remind you that with version 1.x we already have the Delete and AcceptChanges/RejectChanges methods to accomplish this.
The GetTableReader Method
The GetTableReader method is a new method that has been added to the DataSet and the DataTable in ADO.NET 2.0. It returns the contents of a DataTable as a DataTableReader (derived from DBDataReader) object. If it is invoked on a DataSet that contains multiple tables, the DataReader will contain multiple resultsets.
The use of the GetTableReader method is quite straight-forward:
Dim dtr As DataTableReader = ds.Tables(0).GetDataReader The DataTableReader works pretty much like the other data readers you have worked with, such as the SqlDataReader or OleDbDataReader. The difference is, however, that rather than streaming data from a live database connection, the DataTableReader provides iteration over the rows of a disconnected DataTable.
The DataTableReader provides a smart, stable iterator. The cached data may be modified while the DataTableReader is active and the reader will automatically maintain its position appropriately even if one or more rows are deleted or inserted while iterating.
A DataTableReader that is created by calling GetDataReader on a DataTable contains one result set with the same data as the DataTable from which it was created. The result set contains only the current column values for each DataRow and rows that are marked for deletion are skipped. A DataTableReader that is created by calling GetDataReader on a DataSet that contains more than one table will contain multiple result sets. The result sets will be in the same sequence as the DataTable objects in the DataSet object's DataTableCollection.
In addition to the features outlined above, another great use of the GetDataReader method is to quickly copy data from one DataTable to another:
Dim dt2 as new DataTable
dt2.Load(ds.Tables(0).GetDataReader)
The DataView.ToTable Method
Another new method that is somewhat related to the previous ones (in that it provides a new DataTable cache of existing data) and is worth mentioning is the ToTable method of the DataView class. As a reminder, the DataView class provides a logical view of the rows in a DataTable. This view may be filtered by row, row state, and sorted. However, in ADO.NET 1.1, there is no easy way to save or pass on the rows of the view, since the DataView does not have its own copy of the rows—it simply accesses the rows of the underlying DataTable as prescribed by the filter and sort parameters. The DataView's ToTable method returns an actual DataTable object that is populated with rows of the exposed by the current view.
Overloaded versions of the ToTable method offer the option of specifying the list of columns to be included in the created table. The generated table will contain the listed columns in the specified sequence, which may differ from the original table/view. This ability to limit the number of columns in a view is a feature that is missing in ADO.NET 1.x and has frustrated many a .NET programmer. You can also specify the name of the created table and whether it should contain all or only distinct rows.
Here is some sample code that shows how to use the ToTable method:
Private Sub ToTableButton_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles ToTableButton.Click
' Show only 2 columns in second grid Dim columns As String() = {"CustomerID", "ContactName"} Dim dt As DataTable = _ds.Tables("customers").DefaultView.ToTable( _"SmallCustomers", False, columns)
DataGridView2.DataSource = dt End Sub Assuming that the contents of the "customers" table in the DataSet ds are displayed in a first grid, this routine displays the newly created DataTable that contains only those rows exposed by the DefaultView (as specified by its filter parameters). The rows in the new table contain only two of the columns of the original DataTable and DataView. An example of this can be seen in Figure 4.
Conclusion
The ADO.Net 2.0 version of the DataSet (and DataTable) introduces numerous new features and enhancements to existing features. The main features, discussed in the article, include significantly improved performance due to a new index engine and the binary serialization format option, extensive capabilities available to a stand-alone DataTable, and mechanisms for exposing cached data as a stream (DataReader) and loading stream data into a DataTable cache. ADO.NET 2.0 also offers greater control over the state of rows in a DataTable, in order to better address more real-world scenarios.
Thanks to Mayank nagar, Kawarjit S. Bedi, Pablo Castro, Alan Griver, Steve Lasker, and Paul Yuknewicz of Microsoft for their help in preparing this article.