65.9K
CodeProject 正在变化。 阅读更多。
Home

独立数据访问层( 文档进行中)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (114投票s)

2006 年 3 月 23 日

CPOL

2分钟阅读

viewsIcon

170340

downloadIcon

1412

通过更改标志在数据库之间切换的艺术

引言

开发人员经常编写使用数据库的应用程序。由于这是非常普遍的,因此他们需要简化与数据访问功能相关的任务。应用程序通常需要根据每个数据库的编程模型进行调整。

背景

System.Data 命名空间 主要包含构成 ADO.NET 体系结构的类。这个命名空间 还定义了许多可以被不同提供者使用的数据访问接口。拥有一个在开发中可用于 Access 2000 数据库,在生产环境中可用于 SQL Server 或 Oracle 数据库的数据访问层组件,应该是一个梦想。难道不是吗?

我是如何考虑这样做的?

Liskov 替换原则可以帮助我们。它指出,派生类必须可以通过基类接口使用,而无需用户知道差异。简单来说,这意味着实现接口的类的对象可以被向上转换为接口类型。我引入这一点是因为它可以帮助我们理解一个非常有用的模式,称为抽象工厂。抽象工厂模式的目的是什么?

抽象工厂类图

抽象工厂设计模式提供了创建相关或依赖对象族的契约,而无需指定它们的具体类。

  • 参与者和协作者
    • AbstractFactory (抽象工厂)
    • ConcreteFactory ConcreteProduct (具体产品)
    • AbstractProduct (抽象产品)
    • 客户端
  • 后果
    • 隔离具体类
    • 轻松交换产品族
    • 促进产品之间的一致性
    • 添加新类型产品可能很困难
  • 实现
    • 抽象工厂通常是单例模式
    • 通常,工厂方法用于创建产品

数据访问层接口

我们需要创建数据访问层对象,但我们也需要系统独立于每个 DAL 的创建方式。下面的代码块显示了表示抽象产品的 IDal 接口。

public interface IDal
{
    IDbCommand CreateCommand();
    IDbCommand CreateCommand( string cmdText );
    IDbCommand CreateCommand( string cmdText, IDbConnection cn );
    IDbCommand CreateCommand( string cmdText, IDbConnection cn, IDbTransaction trans ); 
    IDbConnection CreateConnection();
    IDbConnection CreateConnection( string cnString );
    IDbDataAdapter CreateDataAdapter();
    IDbDataAdapter CreateDataAdapter( IDbCommand selectCmd );
    IDbDataAdapter CreateDataAdapter( string selectCmdText, string selectCnString );
    IDbDataAdapter CreateDataAdapter( string selectCmdText, IDbConnection selectCn );
    IDataReader CreateDataReader( IDbCommand dbCmd );
    IDataReader CreateDataReader( IDbCommand dbCmd, CommandBehavior dbCmdBehavior );
}

实现示例

为了使我的输入/输出参数独立于实现,我使用了通用接口 (System.Data) 作为参数类型。现在是时候实现扩展 IDAL 接口的实际产品了。要做到这一点,我们必须创建一个新类,我将把它命名为 OracleDal。为什么我称它为 OracleDal?因为我想构建一个 Oracle 接入点。当然,您可以在我附带的完整源代码中看到这一点,并且通过单击其他图标,您可以使用许多其他提供者创建不同的对象。下面的示例显示了一个简化的 OracleDal 实现。

Oracle

Oracle

public class OracleDal: IDal
{
    public IDbCommand CreateCommand
        ( string cmdText, IDbConnection cn, IDbTransaction trans )
    {
        IDbCommand oracleCmd = null;

        try
        {
    
            oracleCmd = new OracleCommand( cmdText, 
                (OracleConnection)cn, (OracleTransaction)trans );
        }
        catch( OracleException oracleExc )
        {
            if(oracleCmd != null)
                oracleCmd.Dispose();
            throw new Exception( oracleExc.Message );
        }
        return oracleCmd;
    }
    public IDataReader CreateDataReader(IDbCommand dbCmd, 
                    CommandBehavior dbCmddBehavior )
    {
        IDataReader dr = null;
        try
        {
            dr = dbCmd.ExecuteReader( dbCmdBehavior );
        }
        catch( OracleException oracleExc )
        {
            if( dr != null)
            {
                if(!dr.IsClosed)
                dr.Close();
                dr.Dispose();
            }
            throw new Exception( oracleExc.Message );
        }
        return dr;
    }
    public IDbConnection CreateConnection( string cnString )
    {
        IDbConnection oracleCn = null;
        try
        {
            oracleCn = new OracleConnection( cnString );
        }
        catch( OracleException oracleExc )
        {
            if( oracleCn != null)
            oracleCn.Dispose();
            throw new Exception( oracleExc.Message );
        }
        return oracleCn; 
    }
    public IDbDataAdapter CreateDataAdapter
            ( string selectCmdText, IDbConnection selectCn )
    {
        IDbDataAdapter oracleDataAdapter = null;
        try
        {
            oracleDataAdapter = new OracleDataAdapter
                    ( selectCmdText, (OracleConnection)selectCn );
        }
        catch( OracleException oracleExc )
        {
            throw new Exception( oracleExc.Message );
        }
        return oracleDataAdapter;
    }
}

DB2

DB2

public class DB2Dal: IDal 
{ 
    public IDbCommand CreateCommand( string cmdText, 
    IDbConnection cn, IDbTransaction trans ) 
    { 
        IDbCommand db2Cmd = null; 
        try 
        { 
            db2Cmd = new iDB2Command( cmdText, (db2Connection)cn, 
            (iDB2Transaction)trans ); 
        } 
        catch( iDB2Exception db2Exc ) 
        { 
            if(db2Cmd != null) db2Cmd.Dispose(); 
            throw new Exception( db2Exc.Message ); 
        } 
        return db2Cmd; 
    } 
    public IDataReader CreateDataReader(
        IDbCommand dbCmd, CommandBehavior dbCmddBehavior ) 
    { 
        IDataReader dr = null; 
        try 
        { 
            dr = dbCmd.ExecuteReader( dbCmdBehavior ); 
        } 
        catch( iDB2Exception db2Exc ) 
        { 
            if( dr != null) 
            { 
                if(!dr.IsClosed) dr.Close(); 
                    dr.Dispose(); 
            } 
        throw new Exception( db2Exc.Message ); 
        } 
    return dr; 
    } 
    public IDbConnection CreateConnection( string cnString ) 
    { 
        IDbConnection db2Cn = null; 
        try 
        { 
            db2Cn = new iDB2Connection( cnString ); 
        } 
        catch( iDB2Exception db2Exc ) 
        { 
            if( db2Cn != null) 
                db2Cn.Dispose(); 
        throw new Exception( db2Exc.Message ); 
        } 
        return db2Cn;  
    } 
    public IDbDataAdapter CreateDataAdapter( 
        string selectCmdText, IDbConnection selectCn ) 
    { 
        IDbDataAdapter db2DataAdapter = null; 
        try 
        { 
            db2DataAdapter = new iDB2DataAdapter
                        ( selectCmdText, (iDB2Connection)selectCn ); 
        } 
        catch( iDB2Exception db2Exc ) 
        { 
            throw new Exception( db2Exc.Message ); 
        } 
        return db2DataAdapter; 
    } 
}

SQL Server

Sql Server

public class SqlDal: IDal
{
    public IDbCommand CreateCommand( string cmdText, IDbConnection cn, 
                IDbTransaction trans )
    {
        IDbCommand sqlCmd = null;
        try
        {
            sqlCmd = new SqlCommand( cmdText, (sqlConnection)cn, (SqlTransaction)trans );
        }
        catch( SqlException sqlExc )
        {
            if(sqlCmd != null)
                sqlCmd.Dispose();
        throw new Exception( sqlExc.Message );
        }
        return sqlCmd;
    }
    public IDataReader CreateDataReader
        (IDbCommand dbCmd, CommandBehavior dbCmddBehavior )
    {
        IDataReader dr = null;
        try
        {
            dr = dbCmd.ExecuteReader( dbCmdBehavior );
        }
        catch( SqlException sqlExc )
        {
            if( dr != null)
            {
                if(!dr.IsClosed)
                    dr.Close();
                    dr.Dispose();
            }
            throw new Exception( sqlExc.Message );
        }
        return dr;
    }
    public IDbConnection CreateConnection( string cnString )
    {
        IDbConnection sqlCn = null;
        try
        {
            sqlCn = new SqlConnection( cnString );
        }
        catch( SqlException sqlExc )
        {
            if( sqlCn != null)
                sqlCn.Dispose();
        throw new Exception( sqlExc.Message );
        }
        return sqlCn; 
    }
    public IDbDataAdapter CreateDataAdapter
            ( string selectCmdText, IDbConnection selectCn )
    {
        IDbDataAdapter sqlDataAdapter = null;
        try
        {
            sqlDataAdapter = 
                new SqlDataAdapter( selectCmdText, (SqlConnection)selectCn );
        }
        catch( SqlException sqlExc )
        {
            throw new Exception( sqlExc.Message );
        }
        return sqlDataAdapter;
    }
}

信息

本文的描述不完整。对此我感到抱歉。我将尽快插入其余部分。如果您愿意,可以使用我附带的完整源代码。如果您有任何建议,请与我联系。

© . All rights reserved.