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 ...
随机推荐
- WebAPI返回数据类型解惑 以及怎样解决Extjs无法解析返回的xml
最近开始使用WebAPI,上手很容易,然后有些疑惑 1.WebAPI默认返回什么数据类型,json还是xml? 2.怎么修改WebAPI的返回数据类型,我用IE浏览器请 求返回的数据都是JSON格式的 ...
- m_Orchestrate learning system---二十四、thinkphp里面的ajax如何使用
m_Orchestrate learning system---二十四.thinkphp里面的ajax如何使用 一.总结 一句话总结:其实ajax非常简单:前台要做的事情就是发送ajax请求过来,后台 ...
- Android 自定义的开关按钮——SwitchButton
本文转自:http://blog.csdn.net/swust_chenpeng/article/details/19967501 我将原文的控件进行了一些修改,去掉了原来控件的外边框,只留下重要的遮 ...
- 最简单的UDP程序
最简单的UDP程序,一个负责发送消息,一个接收消息. 发送类: import java.io.IOException; import java.net.DatagramPacket; import j ...
- 隐藏div,文本框角圆滑,消除外边框
#div_1 /*将div设置完成,并且隐藏,当需要的时候对其属性值进行修改*/ { height: 36px; width: 1099px; background-color: #F0DFDF; m ...
- HDU-2303 The Embarrassed Cryptographer 高精度算法(大数取模)
题目链接:https://cn.vjudge.net/problem/HDU-2303 题意 给一个大数K,和一个整数L,其中K是两个素数的乘积 问K的是否存在小于L的素数因子 思路 枚举素数,大数取 ...
- while循环合理运用-判断成绩脚本
在平时的工作生活中,难免不了去写一些交互性质的脚本,然而呢往往有些用户偏偏会输入不合规范的输入,为了避免就此退出脚本重新执行,这时候就可以用while去写一个死循环去针对用户的输出啊.哈哈~他输不对, ...
- Opencv 三次样条曲线(Cubic Spline)插值
本系列文章由 @YhL_Leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/47707679 1.样条曲线简介 样条曲 ...
- ArcGIS api for javascript——地图配置-定制缩放动画,定制缩放框
描述 本例展示了当用户放大或缩小地图时如何定义地图的动画.zoomDuration和zoomRate是Dojo动画属性,他们确定了动画的duration和帧刷新的rate .这些属性单位是毫秒,zoo ...
- 编程算法 - 篱笆修理(Fence Repair) 代码(C)
篱笆修理(Fence Repair) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 把一块木板切成N块, 每次切两块, 分割的开销是木板长度, ...