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 ...
随机推荐
- 【数据压缩】JPEG标准与原理解析
转载请注明出处:http://blog.csdn.net/luoshixian099/article/details/50392230 CSDN-勿在浮沙筑高台 为了满足不同应用的需求,JPEG标准包 ...
- js如何实现简繁体互转
js如何实现简繁体互转 一.总结 一句话总结:其实无论是简体还是繁体,都是在显示端(前端),其实所有的我只用动js就好了,没必要动php. 当然,后端也可以做前端的事情,只是麻烦了点(要多通信两次,第 ...
- 显示gif动画(帧动画的播放)
在android上显示gif不太方便,虽然有控件可以实现,但是效果不是很好,保险点儿的作法还是使用帧动画来处理.①在XML中定义animation-list:<?xml version=&quo ...
- JavaScript 获取移动设备的型号
https://joyqi.com/javascript/how-to-detect-mobile-devices-model-using-javascript.html?utm_source=too ...
- exsi从磁盘中加载虚拟机
e
- pycaffe 可视化常用
net.params['layername'].[0]/[1] caffe的一个程序跑完之后会在snapshot所指定的目录下产生一个后缀名为caffemode的文件,这里存放的就是我们在训练网络的时 ...
- 前端之CSS介绍
CSS介绍 CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素. 当浏览器读到一个样式表,它就会按照这个样式表来对文档进行格式化(渲染). CSS的语法 CSS语 ...
- 用Python爬取影视网站,直接解析播放地址。
记录时刻! 写这个爬虫主要是想让自己的爬虫实用,把脚本放到了服务器,成为可随时调用的接口. 思路算是没思路吧!把影视名带上去请求影视网站,然后解析出我们需要的播放地址. 我也把自己的接口分享出来.接口 ...
- awk 基础的用法
基本的awk执行过程#passwd文件的第二行的第一列和第二列[root@oldboyedu01-nb ~]# awk -F ":" 'NR==2{print $1,$2}' /e ...
- python语法学习笔记
函数的参数 定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了.对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复杂逻辑被封装起来 ...