It seems safe to think about the DataSet component as an in-memory form of a database residing inside a client application instead of being hosted by a database server. In fact, sticking to the strict design goals of the component, this is true. The data manipulation components listed above are all client representations of the database objects one would come across during the course of database design. The database becomes a proper analogy for the DataSet because, just as the former organizes its objects, the DataSet similarly provides a seamlessly integrated and structured code environment for all the client data components to interact concertedly. By exposing the data in a way similar to how it would appear inside the database, the DataSet component brings the true power of database programming to the web-distributed development model.
You do not need to utilize a DataSet component for every client application. Consider the case when you simply need a read-only and forward-only list of items to place in a ComboBox control on a Web Form object. Creating a DataSet to perform this kind of task is a waste of client resources and may have a huge impact on application performance. You may be thinking about populating a DataTable object for such as task. But even then, resources are wasted. In this case, it is better to use a DataReader component—covered in Chapter 2—and loop through its set of retrieved rows to place items into the control.
In general, you should use a DataSet when you need to perform the following tasks:
Retrieve data that you plan to save back to the database. The DataSet and DataAdapter components have a seamless interoperability architecture that allows the DataSet to interact with the database without having any knowledge of the data source (hence the notion of Disconnected Data Source that is central to the .NET Framework’s support for distributed application development).
Convert data from a relational form to a hierarchical form, such as XML. ADO .NET provides tight integration with XML—covered in Chapter 6, “Practical ADO .NET Programming (Part One).”
Combine data from different data sources. The DataSet component allows you to combine data from a limitless number of sources.
Post data to remote components across the Internet. It is possible for remote components to communicate via DataSet components or web services created from DataSet components.
Throughout the rest of this chapter, the component that is central to our discussion is the DataSet component. All the components shown in Figure 3-1 are implemented independently. However, it is important to obtain a solid understanding of the beauty of the DataSet; therefore, all the components are described as they appear in the object model of the DataSet. You will notice that there is not much code in this chapter. This is a reference chapter with a theoretical approach to explaining client data manipulation. Since practical exposure is also very important, Chapter 6 had been dedicated entirely to providing practical experience. Chapter 6 provides information about how to:
Populate the DataSet
Read DataSet content
Save DataSet content
Before the subtle components within the DataSet are covered, let’s examine the properties and methods of the DataSet itself.
Type: Boolean
Attribute: Read/Write
Default: “”
Description: The CaseSensitive property of the DataSet object defines whether any string comparison performed on any data value(s) within the DataSet would be case sensitive or otherwise.
Possible values:
TRUE: String comparisons performed on the DataSet values are case sensitive.
FALSE: String comparisons performed on the DataSet values are not case sensitive.
Type: System.ComponentModel.Container
Attribute: Read-only
Default: “”
Description: The Container property of the DataSet object obtains a valid reference to the object that contains the DataSet.
Type: String
Attribute: Read/Write
Default: “”
Description: The DataSetName property of the DataSet object is used to specify a name for the DataSet object. Setting or getting a name for a DataSet is important if you wish to refer to the particular DataSet by name in the code.
Type: System.Data.DataViewManager
Attribute: Read-only
Default: “”
Description: The DefaultViewManager property of the DataSet object is used to obtain a reference to the default view and organization of data within the DataSet. A DataViewManager object maintains a collection of views for all the DataTable objects within a DataSet.
Type: Boolean
Attribute: Read-only
Default: “”
Description: The DesignMode property of the DataSet object is used to determine whether the particular DataSet is in design mode.
Type: Boolean
Attribute: Read/Write
Default: “”
Description: The EnforceConstraints property is used to indicate whether the DataSet should enforce its defined constraints on data values that it receives when it is being updated. As an in-memory data source, the DataSet component can have constraints defined similar to a data source on a database server. Each DataTable component that is part of a particular DataSet can have its constraints defined using the DataTable’s Constraints property.
Type: System.Data.PropertyCollection
Attribute: Read/Write
Default: “”
Description: The ExtendedProperties property is used to return a collection of custom properties that has been defined for the particular DataSet component. It is also possible to add a custom property to the DataSet using this property.
Type: Boolean
Attribute: Read-only
Default: False
Description: The HasErrors property is used to indicate whether there are any error(s) in any row of a DataTable component inside the particular DataSet component.
Type: System.Globalization.CultureInfo
Attribute: Read
Default: Null
Description: The Locale property is used to obtain information about the locale of the user’s machine. This is a very useful property, as it allows you to define custom actions based on the user’s locale preferences.
Type: String
Attribute: Read/Write
Default: “”
Description: The Namespace property is used to indicate the name of the namespace to which the particular DataSet belongs. This property is most useful when you want to use XML functions to populate an XML document from one or more DataSet components.
Type: String
Attribute: Read/Write
Default: “”
Description: The Prefix property is used to indicate an XML prefix of the DataSet component’s namespace when an XML document is created. The Namespace property should be set prior to defining the Prefix property.
Type: System.Data.DataRelationCollection
Attribute: Read-only
Default: Empty Collection
Description: The Relations property is a collection of DataRelation components that are used within the DataSet component to define the relations between the DataSet’s DataTable components.
Type: System.ComponentModel.ISite
Attribute: Read/Write
Default: Null
Description: The Site property is used to indicate a valid ISite reference for the DataSet. The ISite class enables seamless communication and integration between a .NET component and its container, such as a parent class, Windows Form, or Web Form component.
Type: System.Data.DataTableCollection
Attribute: Read-only
Default: Null
Description: The Tables property is used to obtain a collection of all DataTable component(s) that are available within the DataSet component. If no DataTable component is available within the DataSet, the property has a value of NULL.
As you saw in Figure 3-1, the DataTableCollection component within the DataSet has an entire object model of its own that allows seamless manipulation of data within the DataTable components of a DataSet. This collection and its content are fully covered later in the chapter.
This method instructs the DataSet component to commit all the changes that have been made to its data values since the DataSet was last populated or the last call to this same method was issued.
Call this method to commit all the changes that have been made to a DataSet component. This is useful before you use the DataSet to perform any data transmission to an XML document, a remote object, or the data source through the DataAdapter.
Call this method to initialize a DataSet component when it is contained by another component, a Web Form, or a Windows Form object. Automatic initialization does not occur in any of the three components.
This method removes all the rows of all DataTable components within the DataSet component. Thus, it empties the DataSet component of all its data values.
Call this method when an ultimate housecleaning is needed for a DataSet component. Note that a call to this method does not mean that all DataTables or any of their relations are deleted from the DataSet. These would remain intact until you alter them or destroy the DataSet component.
This method is used to create a new DataSet component that is similar to the particular DataSet on which the method is called.
Use this method when you need to clone the current DataSet component. Note that when you clone the DataSet, no data values are copied across into the new DataSet component created. Only the structure of the DataSet is copied into the new DataSet. If you need to copy data and structure, call the Copy() method.
System.Data.DataSet: A component that is a direct clone and has all the data values of the particular DataSet
This method is used to create a new DataSet component that is similar to and contains the same data values as the particular DataSet on which the method is called.
Use this method when you need to clone the current DataSet component being used and copy all of its data values into the clone. If you need to create a clone without the data values, call the Clone() method.
This method is used to destroy the DataSet component and release the system processing resources that it holds.
This method is useful to effectively manage client resources that a DataSet component is currently utilizing.
Call this method to stop the initialization of a DataSet component when it is contained by another component, a Web Form, or Windows Form object.
System.Data.DataSet: A DataSet component that contains all the changes that had been made since the last call was made to the AcceptChanges() method or the DataSet was loaded
This method is used to create a new DataSet component that holds all the changes that had been made to the current DataSet component.
Use this method when you need to create a DataSet component that contains the changes made by a user to the current DataSet component. This is a good way to allow the application to support undo functionality on the DataSet.
System.Object: An object or component that implements the System.IServiceProvider interface
This method is used to obtain a reference to another component or object that is provided as a service by either the DataSet component or the component or object that is the container of the DataSet.
Use this method when you need to reference a service in your code that would perform some form of desired task or provide data.
This method is used to obtain knowledge of the data type of any component or object in the .NET Framework. In the case of the DataSet, it would return System.DataSet.
The GetType() method is a generic method inherited from the System.Object class. It returns a valid System.Type value that is the data type of the object on which it is called.
This method is used to obtain a string of characters formatted as XML that is the representation of all the data that the DataSet component contains.
Use this method when you wish to obtain a DataSet’s data as a string of XML tags. Note that by using this method, you are simply obtaining an XML string. To write data to a file, you would have to use the WriteXML() method. To obtain a full comprehensive overview of XML integration with ADO .NET, read Chapter 5, “XML Integration with ADO .NET.”
This method is used to obtain a string of characters formatted as XSD schema that is the schema of the XML that is the representation of all the data that the DataSet component contains.
Use this method when you wish to obtain a DataSet’s XML schema as a string. Note that by using this method, you are simply obtaining a string. To write the schema to a file, you would have to use the WriteXMLSchema() method. To obtain a full comprehensive overview of XML integration with ADO .NET, read Chapter 5.
Boolean: A value that indicates whether there have been any changes made to the DataSet component
The default method does not take any parameters. There is an overload to this method that takes the following parameter(s):
System.Data.DataRowState: This enumeration defines the type of changes that you are looking for. Since the HasChanges() method acts on DataRow components of the DataSet’s DataTable components, the DataRowState enumeration defines the state of a DataRow component. Here is a list of possible values of DataRowState and the resulting effect on the HasChanges() method.
Added: The HasChanges() method returns True if there has been any DataRow component(s) added to any DataTable component(s) of the DataSet.
Deleted: The HasChanges() method returns True if there has been any DataRow component(s) deleted from any DataTable component(s) of the DataSet.
Detached: The HasChanges() method returns True if there has been any DataRow component(s) detached from any DataTable component(s) of the DataSet.
Modified: The HasChanges() method returns True if there has been any DataRow component(s) amended in any DataTable component(s) of the DataSet.
Unchanged: This is a bit confusing. You expect the HasChanges() method to return True only if changes have been made to the DataSet. If Unchanged is passed as a filter, the method will return True if the DataSet has not changed and False if it has! This might have some undesirable effect on your application.
This method returns a value indicating whether the data inside the DataSet component has changed from the last time that the AcceptChanges() method was called on the DataSet.
Use this method to check whether the DataSet contains new data. It is usually very useful before an update occurs.
The parameter list that is passed totally depends on the overloaded method that you wish to call:
Overload 1:
System.IO.Stream: This is a Stream component or any other component inheriting from it. A Stream component provides the most generic services for conducting input/output operations with a sequence of bytes.
The DataSet would read its schema information from this Stream component.
String(): An array of String values that contain the namespace URIs that are to be excluded from the schema inference process
Overload 2:
String: A String value that represents the fully qualified path of a file from which the DataSet would infer its schema
String(): An array of String values that contain the namespace URIs that are to be excluded from the schema inference process
Overload 3:
System.IO.TextReader: This is a TextReader component or any other component inheriting from it. A TextReader component provides the most generic services for reading a sequence of characters.
The DataSet would read its schema information from this TextReader component.
String(): An array of String values that contain the namespace URIs that are to be excluded from the schema inference process
Overload 4:
System.Xml.XmlReader: An XmlReader component or any other component inheriting from it. An XmlReader component provides forward-only access to XML data.
The DataSet would read its schema information from this XmlReader component.
To obtain a full comprehensive overview of XML integration with ADO .NET, read Chapter 5, “XML Integration with ADO .NET.”
String(): An array of String values that contains the namespace URIs that are to be excluded from the schema inference process
This method is used to infer the XML schema from a TextReader or XmlReader component or a file into the DataSet.
Use this method when you need to infer the XML schema of a TextReader component or a file into the DataSet.
The parameter list that is passed totally depends on the overloaded method that you wish to call:
Overload 1:
System.Data.DataRow(): This is an array of DataRow components or any other component inheriting from it.
The DataSet would merge its data with the data provided by this array. Merging in this case would be that the DataSet imports data from the DataRow component(s).
Overload 2:
System.Data.DataSet: This is a DataSet component or any other component inheriting from it.
The DataSet on which this method is called would merge its data and schema with those provided by this DataSet.
This is a very powerful way to refresh data inside a client application.
Overload 3:
System.IO.TextReader: This is a TextReader component or any other component inheriting from it. A TextReader component provides the most generic services for reading a sequence of characters.
The DataSet would read its schema information from this TextReader component.
String(): An array of String values that contains the namespace URIs that are to be excluded from the schema inference process
Overload 4:
System.Xml.XmlReader: An XmlReader component or any other component inheriting from it. An XmlReader component provides forward-only access to XML data.
The DataSet would read its schema information from this XmlReader component.
To obtain a full comprehensive overview of XML integration with ADO .NET, read Chapter 5, “XML Integration with ADO .NET.”
String(): An array of String values that contains the namespace URIs that are to be excluded from the schema inference process
Calling the Merge() method causes the DataSet to import the data from the objects that are passed as parameters and merge it with its own data. This is a good way to merge data from two separate DataSet components that have the same schema. Most merge operations are done before the database is updated.
Stream: A Stream object or any object that derives from the Stream class. This parameter is more often a reference to an XML document.
This method is used to obtain a string of characters formatted as XML that is to be stored inside the DataSet component.
Use this method when you wish to populate a DataSet with an XML document or any form of XML source. To write data to a file, you would have to use the WriteXML() method. To obtain a full comprehensive overview of XML integration with ADO .NET, read Chapter 5.
Stream: A Stream object or any object that derives from the Stream class. This parameter is more often a reference to an XML document.
This method is used to obtain a string of characters formatted as the schema of an XML document that is to become the schema of the data stored inside the DataSet component.
Use this method when you wish to apply a particular XML schema to a DataSet from the schema of an XML document or any form of XML source. To obtain a full comprehensive overview of XML integration with ADO .NET, read Chapter 5.
This method is used to reject or roll back all the changes that have occurred to the DataSet component since its AcceptChanges() method was last called.
Use this method when you wish to reject all the changes that occurred to a DataSet. This is a powerful functionality that allows for undo operations and rollback facilities on the client machine.
Use this method when you wish to perform a full rollback of changes made to the DataSet from the time it was initialized in memory.
Use this method when you wish to obtain the representation of the DataSet as a string. The string is not in any specific format. If you want the DataSet’s data as an XML stream, use the GetXml() method.
Stream: A Stream object or any object that derives from the Stream class. This parameter is more often a reference to an XML document.
Use this method when you wish to obtain XML inside a file from a DataSet’s content. It is important to initialize the Stream parameter first. To obtain a full comprehensive overview of XML integration with ADO .NET, read Chapter 5, “XML Integration with ADO .NET.”
Stream: A Stream object or any object that derives from the Stream class. This parameter is more often a reference to an XML document.
This method is used to write the structure of a DataSet component as XML schema to a file.
Use this method when you wish to obtain XML schema inside a file from a DataSet’s structure. It is important to initialize the Stream parameter first. To obtain a full comprehensive overview of XML integration with ADO .NET, read Chapter 5, “XML Integration with ADO .NET.”