LINQ to SQL活学活用(1):这要打破旧观念
程序架构
如今比較经典的架构,看看以下图片。

怎样实现
在一个N层应用程序中我们怎样使用LINQ to SQL呢?这给刚刚入门的朋友的确是个难题,使用LINQ to SQL就是ORM技术,能够非常轻松的实现对数据库记录增删查改操作,可是我们怎样去“构建它”才更合理,更科学,更好用?这才是我们真正要学习的。使用面向对象的接口、抽象达到这个目的,面向接口编程就是更好的选择。能够更好的维护和測试。
以下一步一步完毕这个程序吧,看到标题了吗?这篇是打破旧观念。看看接下来有什么神奇的地方。
首先新建一个project,有两个类库分别为:数据訪问层DataAccess和单元測试UnitTest,看看截图:

数据訪问层
这篇先创建一个数据訪问对象,因为使用LINQ to SQL作为ORM,我们新建一个LINQ to SQL类DataAccessEntities.dbml作为数据訪问对象DataContext。一切可视化的操作,为了展示,在O/R设计器中新建一个Customer类(数据訪问对象)。加入CustomerId、FirstName、LastName三个成员属性。并在成员属性的属性窗体改动对应的属性。

为了展示,这里简单描写叙述下我的操作,设置成员属性例如以下:
- CustomerId:成员属性的类型Int。属性的名称CustomerId,数据库列的名称CustomerId。数据库列參与表的主键True。插入时在数据库中自己主动生成值True,指定插入时自己主动同步属性。
- FirstName:属性的名称FirstName,数据库列的名称FirstName,其他默认
- LastName:属性的名称LastName,数据库列的名称LastName,其他默认
好了,简单的数据訪问对象创建好了,以下測试了~~
单元測试层
单元測试用于測试用例的成功与失败,在软件开发中起着尤为重要的地位。当然使用单元測试的要求非常严格。这个系列我将严格遵守,我整理的要求例如以下
1.尽量在断言中提供错误信息描写叙述,这能够非常easy的发现你的错误。
2.每一个測试全然独立。体现面向对象中的单一职责原则。
3.不要假设数据库中有什么数据或者哪些数据不在数据库中,在每一个測试方法前保证数据库为空的。
4.測试时须要的一些原始数据要作为測试的一部分在測试方法前载入到数据库中。
遵守上面的要求,就可能面临以下的麻烦:
- 在測试前删除每张表的每行数据,PK关联须要另外写删除SQL语句脚本。
- 业务逻辑层创建了你没有预料到的数据,你不优点理。
- 假设你測试失败,在数据库中查看数据不在数据库中,没有不论什么提示信息你不知道系统做了什么。
- 因为记录被锁定,插入数据不写入数据库。也不能在不同数据库连接中读取。
幸好LINQ to SQL做到了上面的一切,LINQ to SQL的DataContext能够用来管理数据架构,它提供了DatabaseExists()、DeleteDatabase()、CreateDatabase()方法能够非常轻松的创建删除数据库。
注意。这个系列我使用NUnit.Framework測试,所以要引用nunit.framework.dll程序集。另外因为代码编写中涉及了这个类库引用System.configuration.dll、System.Data.Linq.dll程序集和Business项目。
1.创建一个測试基类
測试一般是非常复杂的,我们创建一个測试基类用于编写一些通用的方法,然后全部測试类都继承这个測试基类,这个基类主要完毕以下功能。
第一步:手动配置DataContext连接和日志
在我们的数据訪问层只创建了一个数据訪问对象,没有和数据库打交道,測试时须要对DataContext连接到数据库。
另外为了測试显示具体的信息,我们还要使用DataContext的日志功能。
public string ConnectionString
{
get
{
if (ConfigurationManager.ConnectionStrings["conn"] == null ||
String.IsNullOrEmpty(ConfigurationManager.ConnectionStrings["conn"].ConnectionString) == true)
{
throw new InvalidOperationException("默认的连接字符串不存在或者为空");
}
return ConfigurationManager.ConnectionStrings["conn"].ConnectionString;
}
}
private DataAccessEntitiesDataContext m_dataContext;
public DataAccessEntitiesDataContext DataContext
{
get
{
if (m_dataContext == null)
{
m_dataContext = new DataAccessEntitiesDataContext(ConnectionString);
m_dataContext.Log = Console.Out;
}
return m_dataContext;
}
}
第二步:创建数据库
在測试之前。打开暂时连接用于创建数据库。使用DataContext提供了DatabaseExists()、DeleteDatabase()、CreateDatabase()方法,先使用DatabaseExists()验证数据库是否存在,假设存在使用DeleteDatabase()方法删除。使用CreateDatabase()方法创建一个数据库架构,及时释放这个连接。
[TestFixtureSetUp]
public void Init()
{
DataAccessEntitiesDataContext context = new DataAccessEntitiesDataContext(ConnectionString);
context.Log = Console.Out;
if (context.DatabaseExists() == true)
{
context.DeleteDatabase();
}
context.CreateDatabase();
context.Connection.Close();
context.Dispose();
context = null;
}
第三步:关闭全部连接
在測试结束关闭全部的连接,这一步非常必要哦。
[TestFixtureTearDown]
public void Tear()
{
DataContext.Connection.Close();
}
第四步:设置连接字符串
新建一App.config文件。设置连接字符串:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="conn" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=LINQ;Integrated Security=True"/>
</connectionStrings>
</configuration>
2.測试类
我们新建一个測试类用于測试数据訪问对象。这里简单測试创建一个Customer对象。新建CustomerFixture.cs类继承UnitTestBase
编写创建Customer对象方法例如以下,创建一个Customer对象,调用InsertOnSubmit()方法插入,调用DataContext.SubmitChanges()方法提交数据库。
[Test]
public void CreateCustomerTest()
{
Customer customer = new Customer() { FirstName = "YJing", LastName = "Lee" };
Assert.AreEqual(0, customer.CustomerId, "測试前CustomerId为0");
DataContext.Customer.InsertOnSubmit(customer);
DataContext.SubmitChanges();
Assert.AreNotEqual(0, customer.CustomerId, "调用SubmitChanges()方法后CustomerId不为0");
}
測试成功,看看输出结果:

OH!非常酷!首先创建了数据库架构,然后插入了一条数据。再次測试一下这种方法将是什么结果呢?这个问题就留给大家了。
结语
看到了吗?这就是全新的方式来完毕非常酷的工作!
从面向对象入手。利用LINQ to SQL生成其关系型数据库。一切就是这么easy!这篇只在数据訪问层上新建一数据訪问对象,在測试中调用DataContext提供的方法完毕数据操作!
下篇更精彩!
LINQ to SQL活学活用(1):这要打破旧观念的更多相关文章
- JVM活学活用——调优工具
概述 工具做为图形化界面来展示更能直观的发现问题,另一方面一些耗费性能的分析(dump文件分析)一般也不会在生产直接分析,往往dump下来的文件达1G左右,人工分析效率较低,因此利用工具来分析jvm相 ...
- pandas pivot_table 活学活用实例教程
pandas pivot_table 活学活用实例教程 导入相关数据分析的库 首先进行commentTime时间进行数据预处理 查看数据类型信息 最简单的透视表 直接敲击该函数,在notebook中可 ...
- HTML5--details活学活用
这是补充HTML5基础知识的系列内容,其他为: 一.HTML5-- 新的结构元素 二.HTML5-- figure.time.details.mark 三.HTML5-- details活学活用 四. ...
- 活学活用,webapi HTTPBasicAuthorize搭建小型云应用的实践
HTTP使用BASIC认证,WebAPI使用[HTTPBasicAuthorize]标记控制器就是使用了BASIC认证. BASIC认证的缺点HTTP基本认证的目标是提供简单的用户验证功能,其认证过程 ...
- JVM活学活用——优化springboot
介绍 在SpringBoot的Web项目中,默认采用的是内置Tomcat,当然也可以配置支持内置的jetty,内置有什么好处呢? 1. 方便微服务部署. 2. 方便项目启动,不需要下载Tomcat或者 ...
- 活学活用wxPython基础框架
看活活用wxpython这本书,基本框架是这样子的,这里有定义输出,然后打印出整个流程,可以看到是怎样执行的,明天请假了,五一回去玩几天,哈哈,估计假期过来都忘了 import wx import s ...
- JVM活学活用——GC算法 垃圾收集器
概述 垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. jvm 中,程序计数器.虚拟机栈.本地方 ...
- JVM活学活用——类加载机制
类的实例化过程 有父类的情况 1. 加载父类静态 1.1 为静态属性分配存储空间并赋初始值 1.2 执行静态初始化块和静态初始化语句(从上至下) 2. 加载子类静态 2.1 为静态 ...
- JVM活学活用——Jvm内存结构
Java内存结构: JVM内存结构主要是有三大块:堆内存.方法区和栈.堆内存是JVM中最大的一块由年轻代和老年代组成,而年轻代内存又被分为三部分,Eden空间.From Survivor空间.To S ...
随机推荐
- Linux路由表的抽象扩展应用于nf_conntrack
思想 标准IP路由查找的过程为我们提供了一个极好的"匹配-动作"的例程. 即匹配到一个路由项.然后将数据包发给该路由项指示的下一跳.假设我们把上面对IP路由查找的过程向上抽象一个层 ...
- 怎样在Ubuntu手机平台中开发Cordova HTML5应用
我们知道Cordova HTML5应用具有夸平台的特性,同一时候也具有訪问本地一些资源的能力.在今天的这篇文章中.我们将介绍一下怎样创建并执行一个Cordova HTML5的应用到我们的Ubuntu手 ...
- BZOJ4259: 残缺的字符串 & BZOJ4503: 两个串
[传送门:BZOJ4259&BZOJ4503] 简要题意: 给出两个字符串,第一个串长度为m,第二个串长度为n,字符串中如果有*字符,则代表当前位置可以匹配任何字符 求出第一个字符串在第二个字 ...
- jquery重新渲染的问题
今天动态加载了一个a标记,使他被渲染为linkbutton 在拼该a标记串时,将class属性设置为:class='easyui-linkbutton' ,然而却没有看到linkbutton的效果,原 ...
- 关于table布局
html-table 宝贝 状态 单价 数量 商品总价 运费 1sdsdf 2 3fffff 4sdfsfsffsdfs 5dsfs 6
- 深入理解 sudo 与 su 之间的区别
深入理解 sudo 与 su 之间的区别 作者: Himanshu Arora 译者: LCTT zhb127 在早前的一篇文章中,我们深入讨论了 sudo 命令的相关内容.同时,在该文章的末尾有提到 ...
- NodeJS学习笔记 进阶 (9)express+cookie-parser:签名机制深入剖析(ok)
个人总结:这篇文章讲解了express框架种cookie的使用,需要引用cookie-parser这个包.读完这篇文章需要10分钟. 摘选自网络 文章导读 cookie-parser是Express的 ...
- 关于App程序猿泡沫
前言 做开发快七年了,对于程序猿,外行人总有着数不完的讽刺和误解,可是我都懒得去解释.代码搬运工人也好,民工也罢,随他们去说吧.可是网上近期流传的程序猿泡沫,尤其是APP程序猿泡沫的文章导致非常多我们 ...
- 网络芯片应用:GPS公交车行驶记录仪
项目描写叙述 佛罗里达大学学生 Miles Moody 使用WIZnet W5200以太网插板及Arduino Nano剖析了来自一个当地网页服务的HTML代码,并讲述了他每天带着公交车实时GPS坐标 ...
- Perl Learning 5 Hash
[本文原创,未经同意请勿转载] 哈希是一种数据结构,它和数组的相似之处在于能够容纳随意多的值并能按需取用,而它和数组的不同在于索引方式,数组是以数字来索引.哈希则以名字来索引.也就是说.哈希的索引值, ...