Introduction
The era of ADODB. RecordSet and the often forgotten MoveNext has passed, replacing Microsoft ADO. NET with powerful and flexible functions. Our new weapon is the System. Data namespace, which features extremely fast DataReader and a rich set of functions, and is packaged in an object-oriented powerful model. It is not surprising that such a tool can be used. Any three-tier architecture relies on a reliable data access layer (DAL) to perfectly connect the data layer with the business layer. High-quality DAL helps improve code reuse. It is the key to achieving high performance and is completely transparent.
With the improvement of tools, our development model has also changed. Saying goodbye to MoveNext not only frees us from the tedious syntax, but also makes us understand disconnected data, which has a profound impact on the way we develop applications.
Because we are familiar with DataReader and its behavior is very similar to that of RecordSet), we did not take long to develop DataAdapter, DataSet, DataTable, and DataView. It is precisely in the process of developing these new objects that constantly refined skills have changed our development methods. Disconnected data allows us to use the new cache technology, which greatly improves the performance of applications. The functions of these classes allow us to write more intelligent and powerful functions, while also reducing the number of code required for common activities.
In some cases, DataSet is ideal for prototyping, developing small systems, and supporting utilities. However, using DataSet in enterprise systems may not be the best solution, because the ease of maintenance for enterprise systems is more important than the time invested in the market. The purpose of this Guide is to explore an alternative solution for DataSet suitable for processing such work, namely, custom entities and collections. Although there are other alternative solutions, they cannot provide the same features or get more support. Our first task is to understand the shortcomings of DataSet so as to understand the problems we want to solve.
Remember, each solution has advantages and disadvantages, so the disadvantages of DataSet may be easier to accept than those of custom entities. You and your team must decide which solution is more suitable for your project. Remember to consider the total cost of the solution, including the substance of the change and the possibility that the time required after production is longer than the time required for actual code development. Finally, please note that the DataSet I mentioned is not a typed DataSet, but it can indeed make up for some shortcomings of the untyped DataSet.
DataSet Problems
Lack of abstraction
The first and most obvious reason for finding alternative solutions is that DataSet cannot extract code from the database structure. DataAdapter can make your code independent from the basic database vendors such as Microsoft, Oracle, and IBM), but cannot abstract the core components of the database: tables, columns, and relationships. These core database components are also the core components of DataSet. DataSet and databases not only share common components, but unfortunately they also share the architecture. Assume that the following Select statement is available:
SELECT UserId, FirstName, LastName
FROM Users
We know that these values can be obtained from datacolumns such as UserId, FirstName, and LastName in DataSet.
Why is it so complicated? Let's look at a basic daily example. First, we have a simple DAL function:
'Visual Basic. NET
Public Function GetAllUsers () As DataSet
Dim connection As New SqlConnection (CONNECTION_STRING)
Dim command As SqlCommand = New SqlCommand ("GetUsers", connection)
Command. CommandType = CommandType. StoredProcedure
Dim da As SqlDataAdapter = New SqlDataAdapter (command)
Try
Dim ds As DataSet = New DataSet
Da. Fill (ds)
Return ds
Finally
Connection. Dispose ()
Command. Dispose ()
Da. Dispose ()
End Try
End Function
// C #
Public DataSet GetAllUsers (){
SqlConnection connection = new SqlConnection (CONNECTION_STRING );
SqlCommand command = new SqlCommand ("GetUsers", connection );
Command. CommandType = CommandType. StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter (command );
Try {
DataSet ds = new DataSet ();
Da. Fill (ds );
Return ds;
} Finally {
Connection. Dispose ();
Command. Dispose ();
Da. Dispose ();
}
}
Then we have a page that uses the repeat to display all users:
<HTML>
<Body>
<Form id = "Form1" method = "post" runat = "server">
<Asp: Repeater ID = "users" Runat = "server">
<ItemTemplate>
<% # DataBinder. Eval (Container. DataItem, "FirstName") %>
<Br/>
</ItemTemplate>
</Asp: Repeater>
</Form>
</Body>
</HTML>
<Script runat = "server">
Public sub page_load
Users. DataSource = GetAllUsers ()
Users. DataBind ()
End sub
</Script>
As we can see, our ASPX page uses the DAL function GetAllUsers as the DataSource of the repeat. If, for some reason, the database architecture changes due to degradation for performance, standardization for clarity, and requirements changes, the changes will always affect ASPX, that is, Databinder that affects the use of the "FirstName" column name. eval row. This immediately generates a dangerous signal in your mind: Will changes in the database architecture affect the ASPX code? It doesn't sound like N layers, right?
If all we have to do is simply rename the column, it is not complicated to change the code in this example. However, if GetAllUsers is used in many places and worse, what if it is used as a Web service that provides services to countless users? How can we easily or securely disseminate changes? For this basic example, the stored procedure itself may be sufficient as an abstraction layer. However, relying on stored procedures to obtain functions other than basic protection may cause greater problems in the future. This can be considered as hard encoding. In essence, when using DataSet, you may need to establish a strict connection between the database architecture, regardless of the column name or serial number location) and the Application/business layer. Hopefully, previous experience or logic will help you understand the impact of hard coding on maintenance and future development.
Another reason DataSet cannot provide proper abstraction is that it requires developers to understand the infrastructure. We are not talking about basic knowledge, but all the knowledge about column names, types, and relationships. Removing this requirement not only makes your code less interrupted as we see, but also makes the code easier to write and maintain. Simply put:
Convert. ToInt32 (ds. Tables [0]. Rows [I] ["userId"]);
It is not only difficult to read, but also requires familiarity with column names and their types. Ideally, your business layer does not need to know anything about the basic database, database architecture, or SQL. If you use CodeBehind using DataSet as in the preceding code string, your business layer may be thin.