270 likes | 466 Views
Creating the Product Catalog. Part 1. Roadmap for This Chapter. To implement the departments list, you’ll start with the database and make your way to the presentation tier :
E N D
Creating the Product Catalog Part 1
Roadmap for This Chapter To implement the departments list, you’ll start with the database and make your way to the presentation tier: 1. You’ll create the Department table in the database. This table will store data regarding the store’s departments. Before adding this table, you’ll learn the basic concepts of working with relational databases. 2. You’ll add the GetDepartments stored procedure to the database, which (like all the other stored procedures you’ll write) is logically located in the data tier part of the application. At this step, you’ll learn how to speak with relational databases using SQL.
Roadmap for This Chapter 3. You’ll create the business tier components of the departments list. You’ll learn how to communicate with the database by calling the stored procedure and sending the results to the presentation tier. 4. Finally, you’ll implement the DepartmentsList.ascx Web User Control to display a dynamic list of departments for your visitor, which is the goal of this chapter.
Storing Catalog Information • We’ll briefly discuss the main parts that make up a database table: • Primary keys • UNIQUE columns • SQL Server data types • Nullable columns and default values • Identity columns • Indexes
Indexes You should keep the following in mind about indexes: • Indexes greatly increase search operations on the database, but they slow down operations that change the database (delete, update, and insert operations). • Having too many indexes can slow down the general performance of the database. The general rule is to set indexes on columns frequently used in WHERE, ORDER BY, and GROUP BY clauses, used in table joins, or having foreign-key relationships with other tables. • Indexes are automatically created on primary key and unique table columns.
Creating the Department Table Add two sample data
Communicating with the Database • The ultimate goal with the table is to get the list of department names from the database using C# code. • Stored procedures are database objects that store programs written in T-SQL. Much like normal functions, stored procedures accept input and output parameters and have return values.
Stored procedures adv. • Storing SQL code as a stored procedure usually results in better performance because SQL Server generates and caches the stored procedure execution plan when it’s first executed. • Using stored procedures allows for better maintainability of the data access and manipulation code, which is stored in a central place, and permits easier implementation of the three-tier architecture (the stored procedures forming the data tier).
Stored procedures adv. • Security can be better controlled because SQL Server permits setting different security permissions for each individual stored procedure. • SQL queries created ad hoc in C# code are more vulnerable to SQL injection attacks, which is a major security threat. • This might be a matter of taste, but having the SQL logic separated from the C# code keeps the C# code cleaner and easier to manage; it looks better to call the name of a stored procedure than to join strings to create a SQL query to pass to the database.
Create the stored procedure CREATE PROCEDURE GetDepartments AS SELECT DepartmentID, Name, Description FROM Department
Adding Logic to the Site The business tier (or middle tier) is said to be the brains of the application because it manages the application’s business logic. For the business tier of the departments list, you’ll implement three classes: • GenericDataAccess implements common functionality that you’ll then reuse whenever you need to access the database. Having this kind of generic functionality packed in a separate class saves keystrokes and avoids bugs in the long run. • CatalogAccess contains product catalog–specific functionality, such the GetDepartmentsmethod that will retrieve the list of departments from the database. • BalloonShopConfiguration and Utilities contain miscellaneous functionality such as sending emails, which will be reused in various places in BalloonShop.
Choosing Technologies and Tools • No matter which architecture is chosen, a major question that arises in every development project is which technologies, programming languages, and tools are going to be used, bearing in mind that external requirements can seriously limit your options. • The system requirements and software requirements stages in the software development process will determine which technologies you must use for creating the application.
Connecting to SQL Server • The main challenge is to understand how the code that accesses the database works. The .NET technology that permits accessing a database from C# code is called ADO.NET. • ADO.NET groups all .NET classes that are related to database access. • Each database operation always consists of three steps: 1. Open a connection to the SQL Server database. 2. Perform the needed operations with the database and get back the results. 3. Close the connection to the database.
Cont. • The class used to connect to SQL Server is SqlConnection. • When creating a new database connection, you always need to specify at least three important pieces of data: • The name of the SQL Server instance you’re connecting to • The authentication information that will permit you to access the server • The database you want to work with
example // Create the connection object SqlConnection connection = new SqlConnection(); // Set the connection string connection.ConnectionString = "Server=(local)\SqlExpress; " + "User ID=balloonshop; Password=ecommerce;" + "Database=BalloonShop"; // Open the connection connection.Open(); Or // Create the connection object and set the connection string SqlConnection connection = new SqlConnection("... connection string ..."); // Open the connection connection.Open();
Issuing Commands and Executing Stored Procedures // Create the command object SqlCommand command = new SqlCommand(); command.Connection = connection; command.CommandText = "CatalogGetDepartments"; command.CommandType = CommandType.StoredProcedure; Or // Create the command object SqlCommand command = new SqlCommand("GetDepartments", connection); command.CommandType = CommandType.StoredProcedure;
Executing the Command and Closing the Connection • Three Execute methods of the SqlCommand class: • ExecuteNonQuery • ExecuteScalar • ExecuteReader
ExecuteNonQuery • is used to execute a SQL statement or stored procedure that doesn’t return any records. Used when executing operations that update, insert, or delete information in the database. • ExecuteNonQuery returns an integer value that specifies how many rows were affected by the connection.Open(); command.ExecuteNonQuery(); command.Close();
ExecuteScalar • is like ExecuteNonQuery in that it returns a single value, although it returns a value that has been read from the database instead of the number of affected rows. It is used in conjunction with SELECT statements that select a single value. • If SELECT returns more rows and/or more columns, only the first column in the first row is returned. • E.g: SELECT COUNT(*) FROM
ExecuteReader • is used with SELECT statements that return multiple records • ExecuteReader returns a SqlDataReader object, which contains the results of the query. • A SqlDataReader object reads and returns the results one by one, in a forward-only and read-only manner. The good news about the SqlDataReader is that it represents the fastest way to read data from the database, and the bad news is that it needs an open connection to operate—no other database operations can be performed on that connection until the reader is closed. • Another solution is to load all the data returned by the SqlDataReader into a DataTableobject which will allow you to close the database connection very quickly.
eXample Here’s a simple example of reading some records from the database and saving them to a DataTable: // Open the connection conn.Open(); // Create the SqlDataReader object by executing the command SqlDataReader reader = comm.ExecuteReader(); // Create a new DataTable and populate it from the SqlDataReader DataTable table = new DataTable(); table.Load(reader); // Close the reader and the connection reader.Close(); conn.Close();
Implementing Generic Data Access Code // Create a new database provider factory DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.SqlClient"); // Create the connection object DbConnection conn = factory.CreateConnection(); // Initialize the connection string conn.ConnectionString = "... connection string ..."; // Create the command object and set its properties DbCommandcomm = conn.CreateCommand(); comm.CommandText = "CatalogGetDepartments"; comm.CommandType = CommandType.StoredProcedure; // Open the connection conn.Open(); // Execute the command and save the results in a DataTable DbDataReader reader = comm.ExecuteReader(); DataTable table = new DataTable(); table.Load(reader); // Close the reader and the connection reader.Close(); conn.Close();
Catching and Handling Exceptions • The general strategy to deal with runtime exceptions is as follows: • If the error is not critical, deal with it in code, allowing the code to continue executing normally, and the visitor will never know an error happened. • If the error is critical, handle it partially with code to reduce the negative effects as much as possible, and then let the error propagate to the presentation tier that will show the visitor a nice-looking “Houston, we have a problem” page. • For the errors that you can’t anticipate, the last line of defense is still the presentation tier, which logs the error and politely asks the visitor to come back later.
Try – catch – finally construct try { // code that might generate an exception } catch (Exception ex) { // code that is executed only in case of an exception // (exception's details are accessible through the ex object) //it is optional } finally { // code that executes at the end, no matter if // an exception was generated or not //it is optional }
Sending Emails • To send emails, you need the SmtpClient and MailMessage classes from the System.Net.Mailnamespace. • MailMessage has four important properties that you set before sending an email: From, To, Subject, and Body. • When working with SmtpClient, you can set its Host property to the address of an external SMTP server; otherwise, the mail is sent through the local SMTP service in Windows.