程序架构

如今比較经典的架构,看看以下图片。

怎样实现

在一个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):这要打破旧观念的更多相关文章

  1. JVM活学活用——调优工具

    概述 工具做为图形化界面来展示更能直观的发现问题,另一方面一些耗费性能的分析(dump文件分析)一般也不会在生产直接分析,往往dump下来的文件达1G左右,人工分析效率较低,因此利用工具来分析jvm相 ...

  2. pandas pivot_table 活学活用实例教程

    pandas pivot_table 活学活用实例教程 导入相关数据分析的库 首先进行commentTime时间进行数据预处理 查看数据类型信息 最简单的透视表 直接敲击该函数,在notebook中可 ...

  3. HTML5--details活学活用

    这是补充HTML5基础知识的系列内容,其他为: 一.HTML5-- 新的结构元素 二.HTML5-- figure.time.details.mark 三.HTML5-- details活学活用 四. ...

  4. 活学活用,webapi HTTPBasicAuthorize搭建小型云应用的实践

    HTTP使用BASIC认证,WebAPI使用[HTTPBasicAuthorize]标记控制器就是使用了BASIC认证. BASIC认证的缺点HTTP基本认证的目标是提供简单的用户验证功能,其认证过程 ...

  5. JVM活学活用——优化springboot

    介绍 在SpringBoot的Web项目中,默认采用的是内置Tomcat,当然也可以配置支持内置的jetty,内置有什么好处呢? 1. 方便微服务部署. 2. 方便项目启动,不需要下载Tomcat或者 ...

  6. 活学活用wxPython基础框架

    看活活用wxpython这本书,基本框架是这样子的,这里有定义输出,然后打印出整个流程,可以看到是怎样执行的,明天请假了,五一回去玩几天,哈哈,估计假期过来都忘了 import wx import s ...

  7. JVM活学活用——GC算法 垃圾收集器

    概述 垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. jvm 中,程序计数器.虚拟机栈.本地方 ...

  8. JVM活学活用——类加载机制

    类的实例化过程 有父类的情况 1. 加载父类静态    1.1 为静态属性分配存储空间并赋初始值     1.2 执行静态初始化块和静态初始化语句(从上至下) 2. 加载子类静态    2.1 为静态 ...

  9. JVM活学活用——Jvm内存结构

    Java内存结构: JVM内存结构主要是有三大块:堆内存.方法区和栈.堆内存是JVM中最大的一块由年轻代和老年代组成,而年轻代内存又被分为三部分,Eden空间.From Survivor空间.To S ...

随机推荐

  1. Unity游戏开发--30s制作精美地图

    "君子生非异也.善假于物也"--<劝学>荀子 引用这句话的目的,是我觉得有时候.利用工具来提高游戏开发效率是很必要的. 利用工具,解放程序员双手. 今天想给大家介绍下. ...

  2. codeforces #313(div 2)

    B. Gerald is into Art time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  3. sass10 demo1

    index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  4. iOS 报错:(子线程中更新UI)This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.

    今天在写程序的时候,使用Xcode 运行工程时报出下面的错误错信息,我还以为是什么呢,好久没遇到过这样的错误了. **ProjectName[1512:778965] This application ...

  5. js如何实现简繁体互转

    js如何实现简繁体互转 一.总结 一句话总结:其实无论是简体还是繁体,都是在显示端(前端),其实所有的我只用动js就好了,没必要动php. 当然,后端也可以做前端的事情,只是麻烦了点(要多通信两次,第 ...

  6. Python开源爬虫项目代码:抓取淘宝、京东、QQ、知网数据--转

    数据来源:数据挖掘入门与实战  公众号: datadw scrapy_jingdong[9]- 京东爬虫.基于scrapy的京东网站爬虫,保存格式为csv.[9]: https://github.co ...

  7. C#后台请求其它网站页面

    /// <summary> /// 指定Post地址使用Get 方式获取全部字符串 /// </summary> /// <param name="url&qu ...

  8. WLAN 感知

    WLAN 感知 通过 Android 8.0 中新增的 WLAN 感知功能,支持设备可以直接使用 WLAN 感知协议发现其他设备.与其他设备进行互连,以及将覆盖范围扩展到其他设备(Android 9 ...

  9. CMD和AMD的区别

    CMD和AMD俩者之间的区别 AMD和CMD最大的区别是对依赖模块的执行时机处理不同 CMD和AMD都是CommonJS延伸而来的,CommonJS是随着node的出现而出现的,它是一个规范,用于定义 ...

  10. 设置多行文本框不能拓展大小和span标签边框设置

    resize: none;/*设置多行文本框,不能拓展大小*/ #span { display: block; border: 1px solid RGB(169,169,169); /* span标 ...