如何让数据访问过程更透明.
在编写数据库操作方法时我们经常考虑方法内部处理的Connection, Transaction等,主要方便以后不同方法进行整合扩展。但很多时候写数据库操作方法都是封闭,在方法内部打开Connection或Transaction处理;这样即满足现有需求的需要,要省下了调用方法所带来的麻烦事(因为在调用方法里必须定义Connection等信息传进去)。虽然这样满足了现有的需求,但面对以后在功能扩展需要整合几个方法时问题就产生了,因为方法是封闭的当你需多个方法同时使用一个Connection或Transaction就必须修改原有方法;虽然可以对方法重载一个新版来适应新的需要,但是代码的修改和重构也不是一件轻松的工作。
简单地描述一下问题:
public void a()
{
........
}
public void b()
{
…….
}
以上两个方法单独使用并没有什么问题,因为它们都是独立的。当出现下面情况又是如何呢?
Public void c()
{
a();
b();
….
}
在执行这个方法时有可能要保证a和b里面的数据库访问必须使用同一个Connection,如果需要数据完全整性还要确保两个方法的数据操作都必须使用同一个Transaction。由于刚开始编写a和b方法没有考虑这些情况,这个时候我们能做的只有把a和b方法进行重构来满足原有和现在的需要。
如果我们不修改a和b就能满足c的需要那是件多么好的事情,这样开发人员就有更多的时间去处理业务相关的麻烦事情。有时想一下dotNET提供一个DataContext(数据库操作上下文对象)该多好啊,在编写数据库操作代码时不用关心使用什么的Connection和Transaction;通过当前的DataContext来确定。虽然自己有这样的想法去实现,不过dotNET能提供是件最好不过的事情。
Public void c()
{
using(DataContext context = new DataContext())
{
a();
b();
….
}
}
Public void D()
{
using(DataContext context = new DataContext())
{
c();
….
}
}
其实在我的想法中DataContext不一定要显式创建,可以通过配置的方式在中程序设置一个默认的DataContext。
以下代码的功能没有完全实现。
Table orders = new Table("Orders");
Table orderdetails = new Table("[Order Details]");
orderdetails.Delete(OrderDetails._OrderID == 10500);
orders.Delete(Orders._OrderID == 10500);
即使不用显式创建DataContext 上面代码也可以运行。
为了保证数据完整性可以这样做:
using(TransactionContext tran = new TransactionContext())
{
Table orders = new Table("Orders");
Table orderdetails = new Table("[Order Details]");
orderdetails.Delete(OrderDetails._OrderID == 10500);
orders.Delete(Orders._OrderID == 10500);
tran.Commit();
}
如果需要高度透明性,只有一个DataContext是远远不够的,必须提供相应数据操作的封装。