这两层实际上就是大多数实体框架所处的层次,在这两个层次方面,大家可以参考动软的方式,当然,也可以自己构建,也可以利用现有的成熟的实体框架。但对于大型项目或者产品型项目,最好还是不要使用那些复杂的实体框架,因为更新,维护,升级都不太可控,而且很多时候都会有一些限制,不太利于构建高效动态的业务应用(再怎么强大,还是没有直接用SQL语句与数据库打交道强大,而且使用框架时,如果利用了缓存,那么存储过程使用,其它SQL语句的使用,数据的同步都是个大问题)
下面的代码是这两层的一个示例:
1)数据库访问层:
以下是代码片段: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Data.Common; using System.Data.SqlClient; namespace DBHelper { public class DbHelper { /// <summary> /// 执行查询语句,返回DataSet /// </summary> /// <param name="SQLString">查询语句</param> /// <returns>DataSet</returns> public DataSet QueryData(string SQLString, DbConnection conn, DbTransaction Trans) { SqlConnection connection = conn as SqlConnection; connection.Open(); try { DataSet ds = new DataSet(); SqlDataAdapter command = new SqlDataAdapter(SQLString, connection); command.Fill(ds, "ds"); command.Dispose(); return ds; } catch { return null; } } } } |
如果需要支持多种数据库,只要在这里建立一个抽象层,然后根据用户的数据库类型动态的决定采用相应的数据库访问层实例即可。
2)数据访问层:
以下是代码片段: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using DBHelper; using System.Data.Common; namespace HDatabase { public class DynamicDataAccess { public DataTable GetDataTable(string strSQL, DbConnection Conn) { DataSet theDS = new DbHelper().QueryData(strSQL, Conn, null); if (theDS != null && theDS.Tables.Count > 0) { return theDS.Tables[0]; } return null; } } } |
这里可以增加简单的数据访问方法,比如新增,修改,删除等。如果要处理事务的话,在参数中增加一个数据库事务参数,有业务逻辑去决定事务,而不要在底层做。另外要注意的是如果业务逻辑层调用数据访问层方法没有提供数据库连接或者事务的时候,应采用默认的配置创建数据库连接,并不做事务处理。因为毕竟一个系统绝大部分的应用都不会需要时时变更数据库连接。记住:我们之所以在数据访问方法中提供连接与事务参数的目的是为业务逻辑层提供一种可以自行采用的数据连接和事务的手段。