在三层体系结构中,怎么设计数据访问层才能使这个数据访问层能在不同的数据库下都能使用.
我的构想是有一个抽象类DbHelper 封装通用的方法
然后根据不同的数据库实现相应的helper类
数据访问层构造sql语句调用这个dbhelper来执行sql语句现在因为sql server 和oracle的sql语句还有参数设置都不一样.
不知道怎么设计这个数据访问层才能做到通用.
希望高手指点一下.
最好能给出代码.
我这里出了我全部分数求教.

解决方案 »

  1.   

    我也遇到过的,但是我只想到了通过构造函数来决定执行不同的操作
    因为oracle里面对某些数据的操作与sql是不一样的,同时他们所引用的命名空间和操作类也有一些不同
    同时sql语句也有的是不一样的所以我当时仅是靠构造函数来标识该实例在调用一些通用方法的时候是调用sql的还是oracle的..
      

  2.   

    用工厂模式
    http://blog.csdn.net/virlene/archive/2006/05/11/724759.aspx
      

  3.   

    工厂模式是一定要用的
    但是工厂生产什么
    我想生产dbhelper
    不是生产 数据访问层实例
      

  4.   

    thx 谢谢,受教了,一直没有使用过工厂模式,看来我得练练这个了:)
      

  5.   

    我说的通用就是用一个数据访问层,去访问各种数据库
    至于数据库连接是通过dbhelper获得
      

  6.   

    2种方法:
    1、可以去查看ms的petshop 3.0里的sqlhelper和oraclehelper
    2、用orm,如NHibernate
      

  7.   

    用 Orm,IBatisNet 或者 NHibernate,sql语句写在配置文件里面,就算稍做修改的话改下配置文件就行了
      

  8.   


    嗯,petshop里也是用到factory和adapter这些
      

  9.   

    为什么不看看微软的enterprice libary呢?
      

  10.   

    petshop 里同样是写了多个数据访问层
    我是想做一个各个数据库通用的数据访问层
    难到这个要求很过分?
    还是真的没有办法解决?
      

  11.   

    要通用,无非就是在执行的时候,判断连接方法,查询语句,如果这条连接方法不行,则选择另一种方法,如果都不行,那就报错
    try
    {
      ACCESS连接
    }
    catch
    {
      try
      {
        SQL连接
      }
      catch
      {
         try
         {
           ORECAL连接
          }
         catch
         {
            连接数据库语句有错
         }
      }
    }
      

  12.   

    最幼稚的办法就是用强类型数据集了。给项目增加一个数据集,New一个TableAdapter访问SqlServer,再New一个TableAdapter访问Oracle.呵,我知道这不是楼主的意思。只是凑个热闹。
      

  13.   


    这个可以封装成一个DLL了,以后就可以做成数据库操作类库了,呵呵
    看了对工厂模式有了进一步了解了
      

  14.   

    不知道楼主的通用是到什么程度,如果是切换数据库的时候只需做个选择就能操作的话可以用反射,数据访问层调用的是接口方法,用两个类实现对MSSQL和Oracle的操作,这两个类实现同一个接口,这样的话切换数据库的时候传个参数过去就能完成切换了,这样做的话不仅可以切换MSSQL和Oracle,还能实现对任何数据库的支持。
      

  15.   

    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;using Design.Connections;
    using Design.Share;public partial class _Default : System.Web.UI.Page 
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            ConnectionProviderBuilder.SqlConnectionString = "SQL连接字符串";
            ConnectionProviderBuilder.OracleConnectionString = "Oracle连接字符串";
        }    private void Connect2Oracle()
        {
            IConnectionProvider conn = ConnectionProviderBuilder.CreateConnectionProvider(ConnType.Oracle);
            using (conn)
            {
                //conn.BeginTranscation();
                //try
                //{
                    string sql1 = "SELECT * FROM TB WHERE ID=:ID AND NAME=:NAME AND DATA=:DATA";
                    string sql2 = "UPDATE TB SET NAME=:NAME,DATA=:DATA WHERE ID=:ID";                ParamList parms = new ParamList();
                    parms["ID"] = 1;
                    parms["NAME"] = "NAME";
                    parms["DATA"] = DateTime.Now;                conn.ExecuteDataTable(sql1, parms);
                    conn.ExecuteNonQuery(sql2, parms);            //    conn.CommitTranscation();
                //}
                //catch
                //{
                //    conn.RollbackTranscation();
                //}            
            }
        }    private void Connect2SQL()
        {
            IConnectionProvider conn = ConnectionProviderBuilder.CreateConnectionProvider(ConnType.SQL);
            using (conn)
            {
                //conn.BeginTranscation();
                //try
                //{
                string sql1 = "SELECT * FROM TB WHERE ID=@ID AND NAME=@NAME AND DATA=@DATA";
                string sql2 = "UPDATE TB SET NAME=@NAME,DATA=@DATA WHERE ID=@ID";            ParamList parms = new ParamList();
                parms["ID"] = 1;
                parms["NAME"] = "NAME";
                parms["DATA"] = DateTime.Now;            conn.ExecuteDataTable(sql1, parms);
                conn.ExecuteNonQuery(sql2, parms);            //    conn.CommitTranscation();
                //}
                //catch
                //{
                //    conn.RollbackTranscation();
                //}            
            }
        }
    }
      

  16.   

    连接SQL Server和Oracle数据库的不同之处只在于连接字符串的不同而已
    可以使用配置文件确定所连接的数据库及字符串
    就可以实现数据连接层的通用了
      

  17.   

    private void Connect2Oracle() 
    private void Connect2SQL() 还是两个啊
    我是想要一个数据层,就是一个private void Connect()
    我看了大家的想法,首先在这里谢谢先,
    分数不够,我再加.大家一直都在说工厂和反射,
    这两个东西我个人觉得我还是比较了解的.
    而且也用过.
    但是这个问题不是一个工厂和反射能结决的.
    楼上的代码是一个现在很通用的方法,就是写一个oracle的实现
    一个sql的实现.
    这个方案我不喜欢.因为同一个工作,我需要做两次,要把原来sql的转变成为oracle的
    我现在的想法是是不是可以在dbhelper这个层次上做点文章,使得,只写一个具体的跟数据库打交道的就可以了.我先定义个一个dbhelper 然后分别实现sql的和oracle的 在数据访问层,通过反射获得相应的dbhelper实例.
    这是我现在的想法,但是根本不能实现,是我根本不能实现.^_^
    因为在写具体的sql语句(也就是我说的数据访问层)时,两个数据库要求的sql语句完全不一样.
    所以我才在这里问这个问题.
    这个数据访问层应该怎么写?或者说在两个具体的dbhelper 上做点什么?
    我的dbhelper的代码如下: public abstract class DBHelper
        {
            public abstract DbConnection getConnection();        public abstract int ExecuteCommand(string safeSql);        public abstract int ExecuteCommand(string sql, params DbParameter[] values);        public abstract object GetScalar(string safeSql);        public abstract object GetScalar(string sql, params DbParameter[] values);        public abstract DbDataReader GetReader(string safeSql);        public abstract DbDataReader GetReader(string sql, params DbParameter[] values);        public abstract DataTable GetDataSet(string safeSql);        public abstract DataTable GetDataSet(string sql, params DbParameter[] values);        public abstract DbParameter[] getParams(Hashtable table);    }
    }
      

  18.   


    为什么不用MS自己的ADO工厂类呢,
    自己整一个DBHelper获取到属于特定数据库操作的DbProviderFactory类,
    除了SQL语句和SQL参数命名的前缀需要自己处理外其它的,所有的与数据库相关的操作的对像都可以通过这个类去创建本人写过一个可以根据实体生成简单的SQL语句查询的组件(增删改查单表,分页,调用存储过程等操作),参数名称自己生成前缀,调用层真正是做到了一点都不和具体SQL相关我做的这个组件使用了几种常用的设计模型,当然也包括了工厂模型,抽象工厂,楼主不要排斥工厂模型,离了这个东东,要想实现数据库无关,代码又要简练高效,还真不好做
      

  19.   

    参考 Microsoft Data Application BlocksDAAB 3.1微软自己写的,有源代码下载
      

  20.   

    http://download.csdn.net/source/238060