[ASP.NET]91之ASP.NET由浅入深 不负责讲座 Day13 – ADO.NET

[ASP.NET]91之ASP.NET由浅入深 不负责讲座 Day13 – ADO.NET


前言
ADO.NET的范围太广,加上近年来的DataSourceControl与LINQ盛行,所以这边我只做个简介。

糟糕的现象
首先,最常看到糟糕的两种现象,就是一个ASP.NET的工程师,

  1. 要存取DB,只会拖拉DataSourceControl,如SqlDataSource, LinqDataSource等等..
  2. 上面第一点也与这一点息息相关,就是没有将逻辑与数据存取,和呈现层(也就是一般的UI)分隔开来。

为什么使用DataSourceControl会有问题?如果会有问题,又为什么ASP.NET要提供这样子的server control供开发者使用呢?

首先,以目前ASP.NET Webform的设计原点来看,Page Life Cycle就是一个强耦合性的设计,另外Event model也很容易造成耦合性过高的问题。server control封装后提供的方便,很容易开发人员会忽略server control背后的操作过程与方式。而DataSourceControl更是透过精灵的界面,让开发人员可以几近于无脑的一键到底,设好与DB存取的相关设定。

但,这意味着,在.aspx.cs里面,负责UI层的程序就直接与数据存取层搅在一起,所有呈现UI、逻辑判断以及DB存取,都被搅在一起。这是很严重的错误设计方式,完完全全的违背了高内聚低耦合的原则,既不容易做测试,碰到需求异动,也容易产生牵一发而动全身的问题。

针对怎么样将UI与DB存取分开的部分,我们留在后续layer architecture再来探讨。
而我们先针对ADO.NET来取代DataSourceControl做一下概念的介绍。
PS:DataSourceControl我唯一可以接受的是ObjectDataSource,因为它将Business logic与Data Access都透过一个ObjectDataSource做一个接口的隔离。

参考数据
先补上ADO.NET的参考数据:http://msdn.microsoft.com/zh-tw/library/e80y5yhx(VS.80).aspx

ADO.NET入门的步骤
ADO.NET入门的步骤,其实很简单:

  1. 应该要先建立一段SqlConnection,而里面会包含着ConnectionString。
    目的:告诉ASP.NET,我再来这一段SQL是要对哪一个DB server进行操作,我的账号密码是什么。
  2. 建立SqlCommand,需要用到刚刚的SqlConnection,以及我们需要执行的SQL statement。
    目的:将要执行的SQL statement跟要连接的connection组合起来成为一段要执行的command。
  3. Connection打开。
    目的:真的要执行这段SQL statement了,请建立与DB之间的连线。
  4. 执行我们的SQL statement,可能没有回传值,可能有回传值,用一个变量去接。
    目的:得到执行SQL结果
  5. 关掉Connection。
    目的:不占用connection资源。


其他重要Issue
在ADO.NET中,还有两个很重要的issue,
第一个是如何避免SQL injection,SQL injection(原理可参考:http://www.microsoft.com/taiwan/sql/SQL_Injection_G1.htm),
要解决SQL injection最基本的作法,就是使用parameter,各家db provider的范例可参考:http://msdn.microsoft.com/zh-tw/library/dw70f090.aspx

第二个则是事务(transaction)的概念,所谓的事务,简单来说就是我会对DB进行多次异动,这多次异动如果是在同一笔事务中,这些异动应该同时成功(complete)或同时失败且将数据还原为原本的状态(rollback)。举例来说,如同我们去提款机领钱,当我们已经选了提领五千块,正对您的账号数据进行扣款的动作,SQL已经执行完毕,但提款机突然坏了或停电造成事务中断,导致您还没领到真正的钱。这个事务就算失败,钱不该从您的账户扣除,既然您没实际拿到钱,就不应该扣除金额。

通常在ADO.NET里面,使用到的transaction控管叫做TransactionScope,可以参考:http://msdn.microsoft.com/zh-tw/library/h5w5se33(v=VS.80).aspx
PS:如果是跨DB server的事务,也就是分散式事务,要留意MSDTC的问题。(一直是个很麻烦跟啰唆的问题,光设定防火墙就会让人一肚子火了...)

后记
ADO.NET的部分,其实我这边着墨很少,所以只带出一些DB操作与concept而已。
现在很多实际的业务上都是用NHibernate, Spring.NET的AdoTemplate, LINQ to SQL跟LINQ to EF。
比较少有直接使用ADO.NET的。

当后续有比较不错的相关资讯,我会再回补到这一个issue上。


或许您会对下列培训课程感兴趣:

  1. 2019/7/27(六)~2019/7/28(日):演化式设计:测试驱动开发与持续重构 第六梯次(中国台北)
  2. 2019/8/16(五)~2019/8/18(日):【C#进阶设计-从重构学会高易用性与高弹性API设计】第二梯次(中国台北)
  3. 2019/9/21(六)~2019/9/22(日):Clean Coder:DI 与 AOP 进阶实战 第二梯次(中国台北)
  4. 2019/10/19(六):【针对遗留代码加入单元测试的艺术】第七梯次(中国台北)
  5. 2019/10/20(日):【极速开发】第八梯次(中国台北)

想收到第一手公开培训课程资讯,或想询问企业内训、顾问、教练、咨询服务的,请洽 Facebook 粉丝专页:91敏捷开发之路。