asp.net/wingtip/创建数据访问层
一. 什么是数据访问层
在wingtip项目中,数据访问层是对以下三者的总称:
1. product类等数据相关的实体类(class)
2. 数据库(database),对实体类成员的存储
3. 上述二者的交互操作。
product类:
1 using System.ComponentModel.DataAnnotations; 2 3 namespace WingtipToys.Models 4 { 5 public class Product 6 { 7 [ScaffoldColumn(false)] 8 public int ProductID { get; set; } 9 10 [Required, StringLength(100), Display(Name = "Name")] 11 public string ProductName { get; set; } 12 13 [Required, StringLength(10000), Display(Name = "Product Description"), DataType(DataType.MultilineText)] 14 public string Description { get; set; } 15 16 public string ImagePath { get; set; } 17 18 [Display(Name = "Price")] 19 public double? UnitPrice { get; set; } 20 21 public int? CategoryID { get; set; } 22 23 public virtual Category Category { get; set; } 24 } 25 }
database(T-SQL):
1 CREATE TABLE [dbo].[Products] ( 2 [ProductID] INT IDENTITY (1, 1) NOT NULL, 3 [ProductName] NVARCHAR (100) NOT NULL, 4 [Description] NVARCHAR (MAX) NOT NULL, 5 [ImagePath] NVARCHAR (MAX) NULL, 6 [UnitPrice] FLOAT (53) NULL, 7 [CategoryID] INT NULL, 8 CONSTRAINT [PK_dbo.Products] PRIMARY KEY CLUSTERED ([ProductID] ASC), 9 CONSTRAINT [FK_dbo.Products_dbo.Categories_CategoryID] FOREIGN KEY ([CategoryID]) REFERENCES [dbo].[Categories] ([CategoryID]) 10 ); 11 12 13 GO 14 CREATE NONCLUSTERED INDEX [IX_CategoryID] 15 ON [dbo].[Products]([CategoryID] ASC);
二. 让实体类与数据库开始交流
创建好了product类以及对应的数据库,我们接下来要让将二者使用起来。首先是上下文类(context class),这个类负责管理实体类(如product类、category类),并且提供对数据库的访问操作。
productContext类:
1 using System.Data.Entity; 2 namespace WingtipToys.Models 3 { 4 public class ProductContext : DbContext 5 { 6 public ProductContext() 7 : base("WingtipToys") 8 { 9 } 10 11 public DbSet<Category> Categories { get; set; } 12 public DbSet<Product> Products { get; set; } 13 public DbSet<CartItem> ShoppingCartItems { get; set; } 14 public DbSet<Order> Orders { get; set; } 15 public DbSet<OrderDetail> OrderDetails { get; set; } 16 17 } 18 }
在程序第一次运行的时候,数据库虽然已经建立好了数据表,但这是一个空表,如何给这个数据表添加一些数据呢?建立一个ProductDatabaseInitializer类
ProductDatabaseInitializer类:
1 using System.Collections.Generic; 2 using System.Data.Entity; 3 4 namespace WingtipToys.Models 5 { 6 public class ProductDatabaseInitializer : DropCreateDatabaseIfModelChanges<ProductContext> 7 { 8 protected override void Seed(ProductContext context) 9 { 10 GetCategories().ForEach(c => context.Categories.Add(c)); 11 GetProducts().ForEach(p => context.Products.Add(p)); 12 } 13 14 private static List<Category> GetCategories() 15 { 16 var categories = new List<Category> { 17 new Category 18 { 19 CategoryID = 1, 20 CategoryName = "Cars" 21 }, 22 new Category 23 { 24 CategoryID = 2, 25 CategoryName = "Planes" 26 }, 27 new Category 28 { 29 CategoryID = 3, 30 CategoryName = "Trucks" 31 }, 32 new Category 33 { 34 CategoryID = 4, 35 CategoryName = "Boats" 36 }, 37 new Category 38 { 39 CategoryID = 5, 40 CategoryName = "Rockets" 41 }, 42 }; 43 44 return categories; 45 } 46 47 private static List<Product> GetProducts() 48 { 49 var products = new List<Product> { 50 new Product 51 { 52 ProductID = 1, 53 ProductName = "Convertible Car", 54 Description = "This convertible car is fast! The engine is powered by a neutrino based battery (not included)." + 55 "Power it up and let it go!", 56 ImagePath="carconvert.png", 57 UnitPrice = 22.50, 58 CategoryID = 1 59 }, 60 new Product 61 { 62 ProductID = 2, 63 ProductName = "Old-time Car", 64 Description = "There's nothing old about this toy car, except it's looks. Compatible with other old toy cars.", 65 ImagePath="carearly.png", 66 UnitPrice = 15.95, 67 CategoryID = 1 68 }, 69 new Product 70 { 71 ProductID = 3, 72 ProductName = "Fast Car", 73 Description = "Yes this car is fast, but it also floats in water.", 74 ImagePath="carfast.png", 75 UnitPrice = 32.99, 76 CategoryID = 1 77 }, 78 new Product 79 { 80 ProductID = 4, 81 ProductName = "Super Fast Car", 82 Description = "Use this super fast car to entertain guests. Lights and doors work!", 83 ImagePath="carfaster.png", 84 UnitPrice = 8.95, 85 CategoryID = 1 86 }, 87 new Product 88 { 89 ProductID = 5, 90 ProductName = "Old Style Racer", 91 Description = "This old style racer can fly (with user assistance). Gravity controls flight duration." + 92 "No batteries required.", 93 ImagePath="carracer.png", 94 UnitPrice = 34.95, 95 CategoryID = 1 96 }, 97 new Product 98 { 99 ProductID = 6, 100 ProductName = "Ace Plane", 101 Description = "Authentic airplane toy. Features realistic color and details.", 102 ImagePath="planeace.png", 103 UnitPrice = 95.00, 104 CategoryID = 2 105 }, 106 new Product 107 { 108 ProductID = 7, 109 ProductName = "Glider", 110 Description = "This fun glider is made from real balsa wood. Some assembly required.", 111 ImagePath="planeglider.png", 112 UnitPrice = 4.95, 113 CategoryID = 2 114 }, 115 new Product 116 { 117 ProductID = 8, 118 ProductName = "Paper Plane", 119 Description = "This paper plane is like no other paper plane. Some folding required.", 120 ImagePath="planepaper.png", 121 UnitPrice = 2.95, 122 CategoryID = 2 123 }, 124 new Product 125 { 126 ProductID = 9, 127 ProductName = "Propeller Plane", 128 Description = "Rubber band powered plane features two wheels.", 129 ImagePath="planeprop.png", 130 UnitPrice = 32.95, 131 CategoryID = 2 132 }, 133 new Product 134 { 135 ProductID = 10, 136 ProductName = "Early Truck", 137 Description = "This toy truck has a real gas powered engine. Requires regular tune ups.", 138 ImagePath="truckearly.png", 139 UnitPrice = 15.00, 140 CategoryID = 3 141 }, 142 new Product 143 { 144 ProductID = 11, 145 ProductName = "Fire Truck", 146 Description = "You will have endless fun with this one quarter sized fire truck.", 147 ImagePath="truckfire.png", 148 UnitPrice = 26.00, 149 CategoryID = 3 150 }, 151 new Product 152 { 153 ProductID = 12, 154 ProductName = "Big Truck", 155 Description = "This fun toy truck can be used to tow other trucks that are not as big.", 156 ImagePath="truckbig.png", 157 UnitPrice = 29.00, 158 CategoryID = 3 159 }, 160 new Product 161 { 162 ProductID = 13, 163 ProductName = "Big Ship", 164 Description = "Is it a boat or a ship. Let this floating vehicle decide by using its " + 165 "artifically intelligent computer brain!", 166 ImagePath="boatbig.png", 167 UnitPrice = 95.00, 168 CategoryID = 4 169 }, 170 new Product 171 { 172 ProductID = 14, 173 ProductName = "Paper Boat", 174 Description = "Floating fun for all! This toy boat can be assembled in seconds. Floats for minutes!" + 175 "Some folding required.", 176 ImagePath="boatpaper.png", 177 UnitPrice = 4.95, 178 CategoryID = 4 179 }, 180 new Product 181 { 182 ProductID = 15, 183 ProductName = "Sail Boat", 184 Description = "Put this fun toy sail boat in the water and let it go!", 185 ImagePath="boatsail.png", 186 UnitPrice = 42.95, 187 CategoryID = 4 188 }, 189 new Product 190 { 191 ProductID = 16, 192 ProductName = "Rocket", 193 Description = "This fun rocket will travel up to a height of 200 feet.", 194 ImagePath="rocket.png", 195 UnitPrice = 122.95, 196 CategoryID = 5 197 } 198 }; 199 200 return products; 201 } 202 } 203 }
当数据库被创建并且初始化的时候,执行了该类的Seed()方法。这个方法在该类中,是对基类中Seed()方法的重写。执行结束后,数据库中就被填充了类别和产品两类数据。
三. 让web前台使用他们
在web应用启动的时候,为了能够使用我们前边创建好的各个类、数据库、操作逻辑等等,我们需要更新在Global.asax.cs中的Application_Start方法(handler)。
using WingtipToys.Models;
using WingtipToys.Logic;
namespace WingtipToys
{
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
// Initialize the product database.(此处为方法的更新)
Database.SetInitializer(new ProductDatabaseInitializer());
// Create the custom role and user.
RoleActions roleActions = new RoleActions();
roleActions.AddUserAndRole();
// Add Routes.
RegisterCustomRoutes(RouteTable.Routes);
}
...
...其他代码省略...
...
}
}
在web应用启动时,在第一次访问数据的时候(product data),程序会执行指定方法(initializer)来生成数据。
四. 总结
这一章就写这么多,主要是在数据和数据操作层面解释了什么是所谓的“数据访问层”。通过上述三个小节可以看到,“数据访问层”是对实体类(class)、数据库(database,table)、方法(method)的一个统称。对于实体类这样的.cs文件,我们将他们存放在Models文件夹下,也即给他们扣个帽子,“模型”指的就是他们。