一. 什么是数据访问层

在wingtip项目中,数据访问层是对以下三者的总称:
1. product类等数据相关的实体类(class)
2. 数据库(database),对实体类成员的存储
3. 上述二者的交互操作。

product类

 using System.ComponentModel.DataAnnotations;

 namespace WingtipToys.Models
{
public class Product
{
[ScaffoldColumn(false)]
public int ProductID { get; set; } [Required, StringLength(), Display(Name = "Name")]
public string ProductName { get; set; } [Required, StringLength(), Display(Name = "Product Description"), DataType(DataType.MultilineText)]
public string Description { get; set; } public string ImagePath { get; set; } [Display(Name = "Price")]
public double? UnitPrice { get; set; } public int? CategoryID { get; set; } public virtual Category Category { get; set; }
}
}

database(T-SQL)

 CREATE TABLE [dbo].[Products] (
[ProductID] INT IDENTITY (1, 1) NOT NULL,
[ProductName] NVARCHAR (100) NOT NULL,
[Description] NVARCHAR (MAX) NOT NULL,
[ImagePath] NVARCHAR (MAX) NULL,
[UnitPrice] FLOAT (53) NULL,
[CategoryID] INT NULL,
CONSTRAINT [PK_dbo.Products] PRIMARY KEY CLUSTERED ([ProductID] ASC),
CONSTRAINT [FK_dbo.Products_dbo.Categories_CategoryID] FOREIGN KEY ([CategoryID]) REFERENCES [dbo].[Categories] ([CategoryID])
); GO
CREATE NONCLUSTERED INDEX [IX_CategoryID]
ON [dbo].[Products]([CategoryID] ASC);

二. 让实体类与数据库开始交流

创建好了product类以及对应的数据库,我们接下来要让将二者使用起来。首先是上下文类(context class),这个类负责管理实体类(如product类、category类),并且提供对数据库的访问操作。

productContext类

 using System.Data.Entity;
namespace WingtipToys.Models
{
public class ProductContext : DbContext
{
public ProductContext()
: base("WingtipToys")
{
} public DbSet<Category> Categories { get; set; }
public DbSet<Product> Products { get; set; }
public DbSet<CartItem> ShoppingCartItems { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<OrderDetail> OrderDetails { get; set; } }
}

在程序第一次运行的时候,数据库虽然已经建立好了数据表,但这是一个空表,如何给这个数据表添加一些数据呢?建立一个ProductDatabaseInitializer类

ProductDatabaseInitializer类:

 using System.Collections.Generic;
using System.Data.Entity; namespace WingtipToys.Models
{
public class ProductDatabaseInitializer : DropCreateDatabaseIfModelChanges<ProductContext>
{
protected override void Seed(ProductContext context)
{
GetCategories().ForEach(c => context.Categories.Add(c));
GetProducts().ForEach(p => context.Products.Add(p));
} private static List<Category> GetCategories()
{
var categories = new List<Category> {
new Category
{
CategoryID = ,
CategoryName = "Cars"
},
new Category
{
CategoryID = ,
CategoryName = "Planes"
},
new Category
{
CategoryID = ,
CategoryName = "Trucks"
},
new Category
{
CategoryID = ,
CategoryName = "Boats"
},
new Category
{
CategoryID = ,
CategoryName = "Rockets"
},
}; return categories;
} private static List<Product> GetProducts()
{
var products = new List<Product> {
new Product
{
ProductID = ,
ProductName = "Convertible Car",
Description = "This convertible car is fast! The engine is powered by a neutrino based battery (not included)." +
"Power it up and let it go!",
ImagePath="carconvert.png",
UnitPrice = 22.50,
CategoryID =
},
new Product
{
ProductID = ,
ProductName = "Old-time Car",
Description = "There's nothing old about this toy car, except it's looks. Compatible with other old toy cars.",
ImagePath="carearly.png",
UnitPrice = 15.95,
CategoryID =
},
new Product
{
ProductID = ,
ProductName = "Fast Car",
Description = "Yes this car is fast, but it also floats in water.",
ImagePath="carfast.png",
UnitPrice = 32.99,
CategoryID =
},
new Product
{
ProductID = ,
ProductName = "Super Fast Car",
Description = "Use this super fast car to entertain guests. Lights and doors work!",
ImagePath="carfaster.png",
UnitPrice = 8.95,
CategoryID =
},
new Product
{
ProductID = ,
ProductName = "Old Style Racer",
Description = "This old style racer can fly (with user assistance). Gravity controls flight duration." +
"No batteries required.",
ImagePath="carracer.png",
UnitPrice = 34.95,
CategoryID =
},
new Product
{
ProductID = ,
ProductName = "Ace Plane",
Description = "Authentic airplane toy. Features realistic color and details.",
ImagePath="planeace.png",
UnitPrice = 95.00,
CategoryID =
},
new Product
{
ProductID = ,
ProductName = "Glider",
Description = "This fun glider is made from real balsa wood. Some assembly required.",
ImagePath="planeglider.png",
UnitPrice = 4.95,
CategoryID =
},
new Product
{
ProductID = ,
ProductName = "Paper Plane",
Description = "This paper plane is like no other paper plane. Some folding required.",
ImagePath="planepaper.png",
UnitPrice = 2.95,
CategoryID =
},
new Product
{
ProductID = ,
ProductName = "Propeller Plane",
Description = "Rubber band powered plane features two wheels.",
ImagePath="planeprop.png",
UnitPrice = 32.95,
CategoryID =
},
new Product
{
ProductID = ,
ProductName = "Early Truck",
Description = "This toy truck has a real gas powered engine. Requires regular tune ups.",
ImagePath="truckearly.png",
UnitPrice = 15.00,
CategoryID =
},
new Product
{
ProductID = ,
ProductName = "Fire Truck",
Description = "You will have endless fun with this one quarter sized fire truck.",
ImagePath="truckfire.png",
UnitPrice = 26.00,
CategoryID =
},
new Product
{
ProductID = ,
ProductName = "Big Truck",
Description = "This fun toy truck can be used to tow other trucks that are not as big.",
ImagePath="truckbig.png",
UnitPrice = 29.00,
CategoryID =
},
new Product
{
ProductID = ,
ProductName = "Big Ship",
Description = "Is it a boat or a ship. Let this floating vehicle decide by using its " +
"artifically intelligent computer brain!",
ImagePath="boatbig.png",
UnitPrice = 95.00,
CategoryID =
},
new Product
{
ProductID = ,
ProductName = "Paper Boat",
Description = "Floating fun for all! This toy boat can be assembled in seconds. Floats for minutes!" +
"Some folding required.",
ImagePath="boatpaper.png",
UnitPrice = 4.95,
CategoryID =
},
new Product
{
ProductID = ,
ProductName = "Sail Boat",
Description = "Put this fun toy sail boat in the water and let it go!",
ImagePath="boatsail.png",
UnitPrice = 42.95,
CategoryID =
},
new Product
{
ProductID = ,
ProductName = "Rocket",
Description = "This fun rocket will travel up to a height of 200 feet.",
ImagePath="rocket.png",
UnitPrice = 122.95,
CategoryID =
}
}; return products;
}
}
}

当数据库被创建并且初始化的时候,执行了该类的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文件夹下,也即给他们扣个帽子,“模型”指的就是他们。

asp.net/wingtip/创建数据访问层的更多相关文章

  1. 在 ASP.NET 中创建数据访问和业务逻辑层(转)

    .NET Framework 4 当在 ASP.NET 中处理数据时,可从使用通用软件模式中受益.其中一种模式是将数据访问代码与控制数据访问或提供其他业务规则的业务逻辑代码分开.在此模式中,这两个层均 ...

  2. ClownFish:比手写代码还快的通用数据访问层

    http://www.cnblogs.com/fish-li/archive/2012/07/17/ClownFish.html 阅读目录 开始 ClownFish是什么? 比手写代码还快的执行速度 ...

  3. asp.net/wingtip/显示数据和详细信息

    前边我们的工作处于wingtip工程基础建设阶段,先是建立了“数据访问层”,然后设计建设了“UI和导航”的框架,接下来要充实工程的内容,显示“数据和详细信息”. 一. 添加数据控件(Data Cont ...

  4. 使用JDBC构建简单的数据访问层

    本教程的目的是使用Java编写的分离的层去访问数据库中的表,这一层通常称为数据访问层(DAL) 使用DAL的最大好处是通过直接使用一些类似insert()和find()的方法简化了数据库的访问操作,而 ...

  5. 使用Ninject+Moq在单元测试中抽象数据访问层

    一.测试方法的业务逻辑时,通常都需要从数据库读取测试数据,但是每次初始化数据库数据都很麻烦,也会影响到其它业务对数据的访问,怎样抽象数据访问层呢?就是用Moq去模拟数据访问的逻辑     二.步骤如下 ...

  6. 企业级应用架构(三)三层架构之数据访问层的改进以及测试DOM的发布

    在上一篇我们在宏观概要上对DAL层进行了封装与抽象.我们的目的主要有两个:第一,解除BLL层对DAL层的依赖,这一点我们通过定义接口做到了:第二,使我们的DAL层能够支持一切数据访问技术,如Ado.n ...

  7. 数据访问层的改进以及测试DOM的发布

    数据访问层的改进以及测试DOM的发布 在上一篇我们在宏观概要上对DAL层进行了封装与抽象.我们的目的主要有两个:第一,解除BLL层对DAL层的依赖,这一点我们通过定义接口做到了:第二,使我们的DAL层 ...

  8. NHibernate:教你如何搭建数据访问层?

    NHibernate:教你如何搭建数据访问层? 什么是NHibernate NHibernate 是一个基于.net 的针对关系型数据库的对象持久化类库.NHibernate 来源于非常优秀的基于Ja ...

  9. 项目架构开发:数据访问层之Cache

    数据访问层简单介绍 数据访问层,提供整个项目的数据访问与持久化功能.在分层系统中所有有关数据访问.检索.持久化的任务,最终都将在这一层完成. 来看一个比较经典的数据访问层结构图 大概可以看出如下信息 ...

随机推荐

  1. MyEclipse最新版-版本更新说明及下载 - MyEclipse官方中文网

    http://www.myeclipsecn.com/learningcenter/myeclipse-update/ [重要更新]MyEclipse 2015正式版发布 [重要更新]MyEclips ...

  2. 爱奇艺技术分享:爱奇艺Android客户端启动速度优化实践总结

    本文由爱奇艺技术团队原创分享,原题<爱奇艺Android客户端启动优化与分析>. 1.引言 互联网领域里有个八秒定律,如果网页打开时间超过8秒,便会有超过70%的用户放弃等待,对Andro ...

  3. 吴恩达机器学习笔记52-异常检测的问题动机与高斯分布(Problem Motivation of Anomaly Detection& Gaussian Distribution)

    一.问题动机 异常检测(Anomaly detection)问题是机器学习算法的一个常见应用.这种算法的一个有趣之处在于:它虽然主要用于非监督学习问题,但从某些角度看,它又类似于一些监督学习问题. 给 ...

  4. [Swift]LeetCode149. 直线上最多的点数 | Max Points on a Line

    Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. ...

  5. [Swift]LeetCode448. 找到所有数组中消失的数字 | Find All Numbers Disappeared in an Array

    Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and ot ...

  6. [Swift]LeetCode746. 使用最小花费爬楼梯 | Min Cost Climbing Stairs

    On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed). Once you pay ...

  7. [Swift]LeetCode862. 和至少为 K 的最短子数组 | Shortest Subarray with Sum at Least K

    Return the length of the shortest, non-empty, contiguous subarray of A with sum at least K. If there ...

  8. [Swift]LeetCode913.猫与老鼠 | Cat and Mouse

    A game on an undirected graph is played by two players, Mouse and Cat, who alternate turns. The grap ...

  9. Mysql、Hbuilder、Idea快捷键

    MyEclipse 快捷键 ↑ ↓ ← →多 1.方法抽取,Alt+Shift+M 2.多行注释:Ctrl+Shift+/ 3.对象.方法; Ctrl+2 + ↓+回车 ,自动生成返回类型和变量 (非 ...

  10. “百度杯”CTF比赛(二月场)-web-writeup

    爆破一: 打开网页看到源代码: 根据提示这题就是找变量的值,本想爆破,但不太现实.百度 php获取变量的值 有个超全局数组 $GLOBALS 爆破二: 打开网页看到源代码: 看到了eval() 函数, ...