一. 什么是数据访问层

在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. [Swift]LeetCode58. 最后一个单词的长度 | Length of Last Word

    Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the l ...

  2. [Swift]LeetCode228. 汇总区间 | Summary Ranges

    Given a sorted integer array without duplicates, return the summary of its ranges. Example 1: Input: ...

  3. [Swift]LeetCode528. 按权重随机选择 | Random Pick with Weight

    Given an array w of positive integers, where w[i] describes the weight of index i, write a function  ...

  4. [SQL]LeetCode601. 体育馆的人流量 | Human Traffic of Stadium

    SQL架构 Create table If Not Exists stadium (id int, visit_date DATE NULL, people int) Truncate table s ...

  5. 使用Task

    http://www.cnblogs.com/Charltsing/p/taskpoolthread.html task默认对线程的调度是逐步增加的,连续多次运行并发线程,会提高占用的线程数,而等若干 ...

  6. Ceres Solver 在win8+vs2013环境下的安装

    参考博文:https://blog.csdn.net/wzheng92/article/details/79504709

  7. mysql主从集群配置

    1.二进制日志 主: #master vim /etc/mysql/my.cnf #server-id server-id=2 #二进制日志 log-bin=musql-bin#statement r ...

  8. [Abp 源码分析]四、模块配置

    0.简要介绍 在 Abp 框架当中通过各种 Configuration 来实现模块的配置,Abp 本身提供的很多基础设施功能的一些在运行时的行为是通过很多不同的 Configuration 来开放给用 ...

  9. Nginx篇--Nginx源码搭建

    Nginx安装步骤: 1.依赖 gcc openssl-devel pcre-devel zlib-devel    安装:yum install gcc openssl-devel pcre-dev ...

  10. 上下div高度动态自适应--另类处理方案

    这段时间在工作中遇到一个看似较为棘手的问题.问题描述:查询报表页面分为上下两部分,上部分为条件输入区域,下部分为报表展示区域.客户要求做到默认满屏(但要动态适应不同的窗体大小,也就是浏览器窗体用户会手 ...