Beginning ASP.NET 2.0 E-Commerce in C# 2005 From Novice to Professional PHẦN 3 docx

70 467 0
Beginning ASP.NET 2.0 E-Commerce in C# 2005 From Novice to Professional PHẦN 3 docx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Darie-Watson_4681C04.fm Page 119 Monday, September 19, 2005 9:51 AM CHAPTER ■ CREATING THE PRODUCT CATALOG: PART II Expand your database node in Database Explorer, right-click the Database Diagrams node, and select Add New Diagram from the context menu (alternatively, you can choose Data ➤ Add New ➤ Diagram) If a dialog box that asks about creating database objects required for diagramming shows up, click Yes You’ll see a dialog box as shown in Figure 4-12 Click Add four times to add all your tables to the diagram, and then click Close Figure 4-12 Adding tables to the diagram Feel free to zoom the window and rearrange the tables on the diagram to fit nicely on the screen With the default options, your diagram will look like Figure 4-13 Figure 4-13 Adding tables to the diagram 119 Darie-Watson_4681C04.fm Page 120 Monday, September 19, 2005 9:51 AM 120 CHAPTER ■ CREATING THE PRODUCT CATALOG: PART II To enforce the Many-to-Many relationship between Category and Product, you need to add two FOREIGN KEY constraints In this exercise, you’ll create these constraints visually 10 Click the ProductID key in the ProductCategory table and drag it over the ProductID column of the Product table The dialog box that adds a new foreign-key relationship shows up, already filled with the necessary data (see Figure 4-14) Figure 4-14 Creating a new foreign key 11 Click OK to confirm adding the foreign key, and then click OK again to close the Foreign Key Relationship dialog box 12 Create a new relationship between the Category and ProductCategory tables on their CategoryID columns in the same way you did in steps 11 and 12 The diagram now reflects the new relationships (see Figure 4-15) Figure 4-15 Viewing tables and relationships using the database diagram Darie-Watson_4681C04.fm Page 121 Monday, September 19, 2005 9:51 AM CHAPTER ■ CREATING THE PRODUCT CATALOG: PART II 13 Press Ctrl+S to save your diagram and the changes you made to your tables When asked for a diagram name, type CatalogDiagram You’ll be warned that Product, Category, and ProductCategory will be saved to the database Click Yes to confirm 14 Populate the ProductCategory table by running the PopulateProductCategory.sql script provided in the Source Code area on the Apress web site How It Works: Many-to-Many Relationships and Database Diagrams In this exercise, you created the Product table and implemented (and enforced) a Many-to-Many relationship with Category Many-to-Many relationships are created by adding a third table, called a junction table, which is named ProductCategory in this case This table contains (ProductID, CategoryID) pairs, and each record in the table associates a particular product with a particular category So, if you see a record such as (1,4) in ProductCategory, you know that the product with ProductID belongs to the category with CategoryID The Many-to-Many relationship is physically enforced through two FOREIGN KEY constraints—one that links Product to ProductCategory, and the other that links ProductCategory to Category In English, this means, “one product can be associated with many product-category entries, each of those being associated with one category.” The foreign keys ensure that the products and categories that appear in the ProductCategory table actually exist in the database and won’t allow you to delete a product if you have a category associated with it and vice versa This is also the first time that you set a primary key consisting of more than one column The primary key of ProductCategory is formed by both its fields: ProductID and CategoryID This means that you won’t be allowed to have two identical (ProductID, CategoryID) pairs in the table However, it’s perfectly legal to have a ProductID or CategoryID appear more than once, as long as it’s part of a unique (ProductID, CategoryID) pair This makes sense, because you don’t want to have two identical records in the ProductCategory table A product can be associated with a particular category, or not; it cannot be associated with a category multiple times At first, all the theory about table relationships can be a bit confusing, until you get used to them To understand the relationship more clearly, you can get a picture by using database diagrams like the ones you worked with in this exercise Database diagrams are very useful If, until now, you could only imagine the relationships between the different tables, the diagram allows you to see what actually happens The diagram you created shows your three One-toMany relationships The diagram also shows the type and direction of the relationships Note that a key symbol appears at the One part of each relationship and an infinity symbol appears at the Many side of the relationship The table whose whole primary key is involved in the relationship is at the One side of the relationship and is marked with the little golden key One of the most useful things about diagrams is that you can edit database objects directly from the diagram If you right-click a table or a relationship, you’ll see a lot of features there Feel free to experiment a bit to get a feeling for the features available Not only can you create foreign keys through the diagram, you can also create new tables, or design existing ones, directly within the diagram To design one of the existing tables, you must switch the table to normal mode by right-clicking the table, and then choosing Table View ➤ Standard When the table is in Standard View mode, you can edit it directly in the diagram, as shown in Figure 4-16 121 Darie-Watson_4681C04.fm Page 122 Monday, September 19, 2005 9:51 AM 122 CHAPTER ■ CREATING THE PRODUCT CATALOG: PART II Figure 4-16 Editing the table directly in the diagram Querying the New Data Now you have a database with a wealth of information just waiting to be read by somebody However, the new elements bring with them a set of new things you need to learn For this chapter, the data-tier logic is a little bit more complicated than in the previous chapter, because it must answer to queries like “give me the second page of products from the ‘Cartoons’ category” or “give me the products on promotion for department X.” Before moving on to writing the stored procedures that implement this logic, let’s first cover the theory about • Retrieving short product descriptions • Joining data tables • Implementing paging Let’s deal with these monsters one by one Retrieving Short Product Descriptions In our web site, product lists don’t display complete product descriptions, but only a portion of them (the full descriptions are shown only in the product details pages) In T-SQL, you get the first characters of a string using the LEFT function After extracting a part of the full description, you append “…” to the end using the + operator The following SELECT query returns all product’s descriptions trimmed at 60 characters, with “…” appended: SELECT LEFT(Description, 60) + ' ' AS 'Short Description' FROM Product The new column generated by the (LEFT(Description, 60) + ' ') expression doesn’t have a name, so we created an alias for it using the AS keyword With your current data, this query would return something like this: Darie-Watson_4681C04.fm Page 123 Monday, September 19, 2005 9:51 AM CHAPTER ■ CREATING THE PRODUCT CATALOG: PART II Short Description An adorable romantic balloon by Simon Elvin You’ll fall in A heart-shaped balloon with the great Elvis on it and the wo A red heart-shaped balloon with "I love you" written on a wh White heart-shaped balloon with the words "Today, Tomorrow a Red heart-shaped balloon with a smiley face Perfect for say A red heart-shaped balloon with "I Love You" in script writi Red heart-shaped balloon with a smiley face and three kisses Joining Data Tables Because the data is stored in several tables, you’ll frequently run into situations in which not all the information you want is in one table Take a look at the following list, which contains data from both the Department and Category tables: Department Name Anniversary Balloons Anniversary Balloons Anniversary Balloons Balloons for Children Balloons for Children Balloons for Children Category Name Love & Romance Birthdays Weddings Message Balloons Cartoons Miscellaneous In other cases, all the information you need is in just one table, but you need to place conditions on it based on the information in another table You cannot get this kind of result set with simple queries such as the ones you’ve used so far Needing a result set based on data from multiple tables is a good indication that you might need to use table joins When extracting the products that belong to a category, the SQL query isn’t the same as when extracting the categories that belong to a department This is because products and categories are linked through the ProductCategory junction table To get the list of products in a category, you first need to look in the ProductCategory table and get all the (ProductID, CategoryID) pairs where CategoryID is the ID of the category you’re looking for That list contains the IDs of the products in that category Using these IDs, you can generate the required product list Although this sounds complicated, it can be done using a single SQL query The real power of SQL lies in its capability to perform complex operations on large amounts of data using simple queries You’ll learn how to make table joins by analyzing the Product and ProductCategory tables and by analyzing how to get a list of products that belong to a certain category Tables are joined in SQL using the JOIN clause Joining one table with another table results in the columns (not the rows) of those tables being joined When joining two tables, there always must be a common column on which the join will be made Suppose you want to get all the products in the category where CategoryID = The query that joins the Product and ProductCategory tables is as follows: 123 Darie-Watson_4681C04.fm Page 124 Monday, September 19, 2005 9:51 AM 124 CHAPTER ■ CREATING THE PRODUCT CATALOG: PART II SELECT ProductCategory.ProductID, ProductCategory.CategoryID, Product.Name FROM ProductCategory INNER JOIN Product ON Product.ProductID = ProductCategory.ProductID The result will look something like this (to save space, the listing doesn’t include all returned rows: ProductID 1 2 3 CategoryID Name -I Love You (Simon Elvin) I Love You (Simon Elvin) Elvis Hunka Burning Love Elvis Hunka Burning Love Elvis Hunka Burning Love Funny Love Funny Love Funny Love The resultant table is composed of the requested fields from the joined tables synchronized on the ProductID column, which was specified as the column to make the join on You can see that the products that exist in more categories are listed more than once, once for each category they belong in, but this problem will go away after we filter the results to get only the products for a certain category Note that in the SELECT clause, the column names are prefixed by the table name This is a requirement if columns exist in more than one table participating in the table join, such as ProductID in our case For the other column, prefixing its name with the table name is optional, although it’s a good practice to avoid confusion The query that returns only the products that belong to category is SELECT Product.ProductID, Product.Name FROM ProductCategory INNER JOIN Product ON Product.ProductID = ProductCategory.ProductID WHERE ProductCategory.CategoryID = The results are ProductID 21 25 39 40 41 42 43 44 45 Name -Baby Hi Little Angel Tweety Stars Toy Story Rugrats Tommy & Chucky Rugrats & Reptar Character Tweety & Sylvester Mickey Close-up Minnie Close-up Teletubbies Time Darie-Watson_4681C04.fm Page 125 Monday, September 19, 2005 9:51 AM CHAPTER ■ CREATING THE PRODUCT CATALOG: PART II 46 47 48 49 50 51 53 54 55 Barbie My Special Things Paddington Bear I Love You Snoopy Pooh Adult Pokemon Character Pokemon Ash & Pikachu Smiley Face Soccer Shape Goal Ball A final thing worth discussing here is the use of aliases Aliases aren’t necessarily related to table joins, but they become especially useful (and sometimes necessary) when joining tables, and they assign different (usually) shorter names for the tables involved Aliases are necessary when joining a table with itself, in which case you need to assign different aliases for its different instances to differentiate them The following query returns the same products as the query before, but it uses aliases: SELECT p.ProductID, p.Name FROM ProductCategory pc INNER JOIN Product p ON p.ProductID = pc.ProductID WHERE pc.CategoryID = Showing Products Page by Page In case certain web sections need to list large numbers of products, it’s useful to let the visitor browse them page by page, with a predefined (or configurable by the visitor) number of products per page Depending on the tier on your architecture where paging is performed, there are two main ways to implement paging: • Paging at the data tier level: In this case, the database returns only the page of products the visitor wants to see • Paging at the presentation tier level: In this scenario, the data tier always returns the complete list of products for a certain section of the site, and the presentation tier objects (such as the GridView control) extract the requested page of products from the complete list This method has potential performance problems especially when dealing with large result sets, because it transfers unnecessarily large quantities of data from the database to the presentation tier Additional data also needs to be stored on the server’s memory, unnecessarily consuming server resources In our web site, we’ll implement paging at the data tier level, not only because of its better performance, but also because it allows you to learn some very useful tricks about database programming that you’ll find useful when developing your web sites Paging at the data tier level can be done in two main ways: • You can use ASP.NET 2.0’s new feature of the DbDataReader object, which has an overload of the ExecuteReader method that takes as parameter the page of records you’re interested in • You can write stored procedures that return only the requested page of products 8213592a117456a340854d18cee57603 125 Darie-Watson_4681C04.fm Page 126 Monday, September 19, 2005 9:51 AM 126 CHAPTER ■ CREATING THE PRODUCT CATALOG: PART II The second alternative is more powerful because of flexibility and performance reasons The automatic paging feature offered by ADO.NET usually doesn’t yield optimal performance because under the hood it uses cursors In case you aren’t a database professional, you don’t need to know what cursors are, besides the fact they usually offer the slowest method of SQL Server data access In the following pages, you’ll learn how to write smart stored procedures that return a specific page of records Say, the first time the visitor searches for something, only the first n matching products are retrieved from the database Then, when the visitor clicks Next page, the next n rows are retrieved from the database, and so on Because for your own project you may need to use various versions of SQL Server, we’ll cover this theory for both SQL Server 2005 and SQL Sever 2000 The optimal method to implement paging using T-SQL code is different for each case because SQL Server 2005 has improvements to the T-SQL language that make your life easier Implementing Paging Using SQL Server 2005 Unlike SQL Server 2000, SQL Server 2005 has a new feature that allows for a very easy implementation of the paging functionality With SQL Server 2000 (and other relational database systems), the main problem is that result sets are always perceived as a group, and individual rows of the set aren’t numbered (ranked) in any way As a consequence, there was no straightforward way to say “I want the sixth to the tenth records of this list of products,” because the database actually didn’t know which those records were ■Note The problem was sometimes even more serious because unless some sorting criteria was implemented, the database didn’t (and doesn’t) guarantee that if the same SELECT statement is run twice, you get the resulted rows in the same order Therefore, you couldn’t know for sure that after the visitor sees the first five products and clicks “Next”, products “six to ten” returned by the database are the ones you would expect To demonstrate the paging feature, we’ll use the SELECT query that returns all the products of the catalog: SELECT Name FROM Product Now, how you take just one portion from this list of results, given that you know the page number and the number of products per page? (To retrieve the first n products, the simple answer is to use the TOP keyword in conjunction with SELECT, but that wouldn’t work to get the next page of products.) SQL Server 2005 has a ROW_NUMBER function that assigns consecutive row numbers, starting with 1, for each row returned by a SELECT statement Because numbering can only be guaranteed to be consistent if a sorting criteria applies to the query, when using ROW_NUMBER, you also need to specify a column on which the rows are ordered prior to being numbered: Darie-Watson_4681C04.fm Page 127 Monday, September 19, 2005 9:51 AM CHAPTER ■ CREATING THE PRODUCT CATALOG: PART II SELECT ROW_NUMBER() OVER (ORDER BY ProductID) AS Row, Name FROM Product This query will have a list of results such as the following: Row -1 10 Name -I Love You (Simon Elvin) Elvis Hunka Burning Love Funny Love Today, Tomorrow & Forever Smiley Heart Red Balloon Love 24 Karat Smiley Kiss Red Balloon Love You Hearts Love Me Tender I Can’t Get Enough of You Baby To retrieve five products, namely the sixth to the tenth products of the list, you transform the previous query into a subquery and filter the results on the WHERE clause of the main query The results of a subquery can be interpreted as a separate table, on which the main query applies (the AS keyword that follows the subquery assigns a name to this virtual “table”) The following T-SQL code returns the specified list of products: SELECT Row, Name FROM( SELECT ROW_NUMBER() OVER (ORDER BY ProductID) AS Row, Name FROM Product ) AS ProductsWithRowNumbers WHERE Row >= AND Row = AND RowNumber

Ngày đăng: 09/08/2014, 14:20

Từ khóa liên quan

Mục lục

  • Beginning ASP.NET 2.0 E-Commerce in C# 2005: From Novice to Professional

    • Chapter 5 Searching the Catalog

Tài liệu cùng người dùng

Tài liệu liên quan