Author: Lu Yan
.NET PETSHOP and DUWAMISH simple introduction
I believe that everyone must have heard the famous "pet shop war", yes, one of the protagonists in this article is the winner .Net Petshop, Microsoft's number of speeds and 1/4 code is far ahead of J2EE-based PetStore pet Shop. Although Sun also complained about this, accusing this "War" has water, but in any case, .Net PETSHOP is definitely a classic .NET instance tutorial, at least a "shortcut" that rushed to J2EE :) Its download address is:
http://www.gotdotnet.com/team/compare
.NET PETSHOP Pet Online Store Home
And Duwamish is a simple, but an extremely complex online bookstore .NET full application example, as a Microsoft's official Sample, which provides two language versions of C # and VB.NET, and there is a lot of Detailed Chinese information, if printing, is home to travel, sleeping into the toilet must have. what? Didn't you hear it? Oh, if you have installed Visual Studio .NET, it is quietly lying quietly on your hard drive, but it is not installed, you can find and install it in your vs.net Enterprise Samples directory, for example : C: / Program Files / Microsoft Visual Studio .NET / Enterprise Samples / Duwamish 7.0 Cs.
DUWAMISH online e-bookstore homepage
Structure brief
Both stores use N-layer applications (there is no doubt that the application architecture of the N-layer structure should be absolutely the first choice for your development .NET application, even if you just want to be a web counter), the difference is that PETSHOP uses The most common three-layer application structure is a representation layer, an intermediate layer, and a data layer. DUWAMISH uses a four-layer application structure and separates from different items, which are representative layers, business appearance layers, service rules layers, and data layers. As for the advantages and disadvantages of these two structures, and why we don't make a detailed discussion, because the focus of this article is not here. We mainly analyze the model of their database programming.
DUWAMISH Data Access Analysis
First, let's take a look at the Duwamish bookstore, which uses DataAdapter and DataSet data storage mode, which is different, which makes a subcatenification extension of DataSet as a data carrier, which is to use custom DataSet to perform layers. Data transfer, the following is a custom DataSet example:
Public Class BookData: DataSet
{
Public boxdata ()
{
//
// Create the Tables in the dataset
//
BuildDataTables ();
}
Private void buildData tables ()
{
//
// Create the Books Table
//
DataTable Table = New DataTable (Books_Table);
DatacolumnCollection columns = Table.columns;
Column.add (pkid_field, typeof (system.int32));
Column.add (type_id_field, typeof (system.int32));
Columns.add (publisher_id_field, typeof (system.int32)); columns.add (publication_year_field, typeof (system.int16));
Column.add (isbn_field, typeof (system.string));
Column.add (image_file_spec_field, typeof (system.string));
Column.add (Title_field, TypeOf (System.String));
Column.add (Description_field, TypeOf (System.String));
Column.add (unit_price_field, typeof (system.decimal);
Column.add (unit_cost_field, typeof (system.decimal);
Column.add (item_type_field, typeof (system.string));
Columns.add (Publisher_name_field, TypeOf (System.String));
This.Tables.Add (Table);
}
.........
}
We can see it has a buildDataTables method, and in the constructor, this, the custom Books table is bundled with this Dataset, and saving column mapping after saving, this is a good idea, how can I not Think? :)
Solve the data structure, then look at the code implementation of the data layer, in Duwamish, 5 classes in the data layer, Books, Categories, Customers, and ORDERS, each class only responsible for access to the data. Below is a sample code for one of the classes:
Private sqldataadapter dscommand;
Public BookData getBookByid (int bookid)
{
Return FillBookData ("GetBookbyid", "@bookid", bookid.toToString ());
}
Private BookData FillbookData (String Paramname, String Paramvalue)
{
IF (dscommand == null)
{
Throw new system.ObjectdisposedException (gettype (). fullname;
}
BookData Data = New BookData ();
Sqlcommand command = dscommand.selectCommand;
Command.comMandText = CommandText;
Command.commandtype = commandType.StoredProcedure; // Use stored proc for perf
SQLParameter Param = New Sqlparameter (paramname, sqldbtype.nvarchar, 255);
Param.Value = paramvalue;
Command.Parameters.Add (param);
DScommand.Fill (DATA);
Return Data;
}
Here is the code of the data layer, we can see that duwamish uses DataAdapter to populate the data into the custom DataSet and then return the Dataset. I am very strange that it can see the specific data access method of getbookbyid in the data access layer. Although there is still an abstract FillBookData method, there are three layers above, the bottom is doing this What do you do? The answer is a data check, and the upper layer is basically doing some strict data legitimacy checks (of course, there will be some complicated transaction logic, but not much), the sample code is as follows: Public CustomerData getCustomerbyemail (String emailaddress, string PASSWORD)
{
//
// check preconditions
//
Applicationassert.checkcondition (EmailAddress! = String.empty, "Email Address Is Required,
Applicationassert.LineNumber);
Applicationassert.checkcondition (password! = String.empty, "Password is required",
Applicationassert.LineNumber);
//
// Get the customer dataset
//
CustomerData DataSet;
Using (DataAccess.customers CustomersDataAccess = New DataAccess.customers ())
{
DataSet = CustomersDataAccess.loadCustomerbyemail (EmailAddress);
}
//
// Verify The Customer's Password
//
DataRowCollection Rows = dataset.tables [CustomerData.customers_table]. ROWS;
IF ((rount.count == 1) && rows [0] [CustomerData.Password_field] .equals (password))
{
Return DataSet;
}
Else
{
Return NULL;
}
}
In this method, it is actually only available for data access.
DataSet = CustomersDataAccess.loadCustomerbyemail (EmailAddress);
In this way, it is the data layer that is directly called. All other are conducting legitimate checks, we can understand how important the system robustness needs to be considered for a real enterprise development.
.NET PETSHOP data access profile
OK, Duwamish is over, let's take a look at the data access mechanism of PETSHOP.
PETSHOP has only one project, which uses the hierarchical method to write the intermediate layer and data layer in the Components directory, where the data layer is a class named Database, which encapsulates all the underlying operations of the database. Below is a sample code segment:
Public void Runproc (String Procname, Out SqlDataReader DataReader)
{
Sqlcommand cmd = createcommand (procname, null);
DataReader = cmd.executeReader (System.Data.commandbehavior.closeConnection);
We saw another data access method with Duwamish, which abstract all the data access methods to make a RunProc method, as for the return data, huh, it is a bit lazy, return to a DataReader to you, you Go to read yourself. Remember what the interlayer data transmission carrier used by DUWAMISH? Yes, it is DataSet, which is returned to the intermediate layer after being filled by the data layer. However, the data transmission carrier of the data layer and the transport layer becomes DataReader. In fact, it is not called a data carrier, because the data has not started reading, here, DataReader's role and pointer a bit similar, maybe we should Call it for "data reference" :)
Then look down, DataReader is "handled":
Public productResults [] getList (String Catid, Int Currentpage, Int PageSize, Ref Int NumResults)
{
NumResults = 0;
INT INDEX = 0;
SqlDataReader Reader = getList (catid);
ProductResults [] results = new productResults [Pagesize];
// Now loop through the list and pull out items of the specified page
INT START = (INT) (CurrentPage - 1) * pageSize
IF (start <= 0) st = 1;
// Skip
For (int i = 0; i IF (Reader.Read ()) NumResults ; } IF (start> 1) reader.read (); // read the data we are intended in While (Reader.Read ()) { IF (INDEX Results [index] = new productResults (); Results [index] .productId = reader.getstring (0); Results [index] .name = reader.getstring (1); INDEX ; } NumResults ; } Reader.Close (); // See if need need to redim array IF (index == pagesize) Return Results; Else { // Not a full Page, Redim Array ProductResults [] results2 = new productResults [index]; Array.copy (Results, Results2, INDEX); Return Results2; } } Do you notice CurrentPage and PageSize? It turned out that the data paging was conducted here, only returned to the minimum amount of data that met, not like a lot of people who like to be lazy, simply bind the entire DataTable a brain to the DataGrid, causing a lot of data redundancy. Here, the data is real read, and is manually filled into a custom object array, let's take a look at the definition of this array: Public Class ProductResults PUBLIC CLASS { PRIVATE STRING M_PRODUCTID; Private string m_name; // Product Props Public string productId { Get {return m_productid;} Set {m_ProductId = value;} } PUBLIC STRING NAME { Get {return m_name;} Set {m_name = value;} } } Very simple, but I am a little strange why not using Struct? Is the performance gap between Struct and Class in .NET already ignore it? analysis Summary By observing the specific implementation of these two stores, we have received two different data access modes, and duwamish uses Dataset as the core, because Dataset provides a large number of related methods this, so the data transmission, data format of the entire application Definitions, data checks are carried out around Dataset, and the entire architecture defines very clear and rigorous, but it is a bit large. PETSHOP did not use a DataSet throughout the program, the program is very simple, light, but there is no duwamish so strong. These two programs are code written by Microsoft's different teams, so they have different styles. However, you should represent the standard mode of .NET. Seeing this, you should have a comparative understanding of the questions that start with the beginning of the article. Also, note that PETSHOP is not immediately read after opening the data connection, but passes the DataReader to another object to perform the data read operation, and then turn off the connection. In this way, the data connection is longer, and the database connection is a very valuable server resource. In contrast, Dawam is filling immediately after connecting the database, and then quickly releases the database connection, which is more conducive to a large number of users. access. One point, the update operation is not mentioned above, and PETSHOP uses the COMMAND object to perform a single stored procedure to update the operation, which belongs to an online instant data update mode. Dawamish uses the DataAdapter's UPDATE method, submits the DataSet's change in a one-time submission to the database, which is an offline data update mode. The advantage of this mode is to update large quantities of data at once, reducing the number of connections to the database. The disadvantage is that if the database needs real-time tracking data change in the event of a very frequent change, it is not suitable. Specific data update methods are required to be used depending on the specific situation. In general, if you only need to quickly read the data and display it, it is recommended that you use DataReader if you need to make a lot of modifications to the data, and there is a large number of incoming access to the possibility, and does not require real-time tracking database changes. It is recommended that you use DataSet. Of course, these two cases are very extreme. The actual application environment may have a very complex condition. Specific need for your own review, comprehensive adoption, but I personally still like Petshop's lighter style :) This article only tries to The data access mechanism of two typical .NET application routines made a simple tracking analysis. If there is hope that other students can do other research or on the topic, please send email to me. Mailbox: Nluyan@163.net, thank you.