数据提供程序抽象



我有一个场景,我需要将几个不同数据提供程序的公共类成员抽象到一个公共类中。 当前 Data 对象都派生自 System.Data.Common 命名空间中的各种Db*类。

以下是我当前的base实现:

public abstract class DataProvider<TConn, TCmd, TParam> : IDisposable
    where TConn : DbConnection, new()
    where TCmd : DbCommand, new() {
    public DataProvider ( string connstr ) {
        ConnectionString = connstr;
    }
    public TConn Connection { get { return new TConn(); } }
    public TCmd Command { get { return new TCmd(); } }
    public string ConnectionString { get; private set; }
    protected DbDataReader ExecuteReader ( string text , CommandType type , params TParam [] parms ) {
        try {
            using ( var conn = Connection ) {
                conn.Open();
                using ( var cmd = Command ) {
                    cmd.CommandText = text;
                    cmd.CommandType = type;
                    cmd.Parameters.AddRange( parms );
                    return cmd.ExecuteReader();
                }
            }
        } catch ( Exception ex ) {
            Log.Exception( ex , GetType().Name );
            throw ex;
        }
    }
}

我当前的两个实现:

public class SqlDataProvider : DataProvider<SqlConnection, SqlCommand, SqlParameter> {
    public SqlDataProvider ( string connstr ) : base( connstr ) { }
    public DataTable ExecuteStoredProcedure(string text, params SqlParameter[] parms ) {
        var dt = new DataTable();
        dt.Load( ExecuteReader( text , CommandType.StoredProcedure , parms ) );
        return dt;
    }
    public DataTable ExecuteStatement(string text, params SqlParameter[] parms ) {
        var dt = new DataTable();
        dt.Load( ExecuteReader( text , CommandType.Text , parms ) );
        return dt;
    }
}
public class OleDataProvider : DataProvider<OleDbConnection, OleDbCommand, OleDbParameter> {
    public OleDataProvider ( string connstr ) : base( connstr ) { }
    public DataTable ExecuteStoredProcedure(string text, params OleDbParameter[] parms ) {
        var dt = new DataTable();
        dt.Load( ExecuteReader( text , CommandType.StoredProcedure , parms ) );
        return dt;
    }
    public DataTable ExecuteStatement(string text, params OleDbParameter[] parms ) {
        var dt = new DataTable();
        dt.Load( ExecuteReader( text , CommandType.Text , parms ) );
        return dt;
    }
}

最终,我正在尝试设置一个框架,以便将来扩展到从Db*对象族派生的其他数据库对象。

当前产品跨越与MS-SQL,Sybase,Informatica和Oracle的连接。 我知道 OleDb 可以对所有 4 种系统类型执行操作,但希望为专用对象构造提供功能(如果可用(。

问题

  1. 实体框架之外,是否有更好的方法?
  2. 我是否正在重复已经存在的工作(在 EF 和/或 ADO 之外(

您需要的唯一类型是连接类型。该连接提供了创建其后续对象的所有方法。

例:

using(var connection = new TConnection())
{
    using(var command = connection.CreateCommand())
    {
        var parameter = command.CreateParameter();
        parameter.ParameterName = "@answer";
        parameter.Value = 42;
        command.Parameters.Add(parameter);
        /// and so forth
    }
}

您甚至可以将其从实际的泛型中移出...这是运行时行为。您所需要的只是您的方法进行IDbConnection,并且您的任何底层方法都不需要知道谁创建了该连接以及它是SqlConnectionOracleConnection还是任何其他连接。

void MyAgnosticDatabaseMethod(IDbConnection connection)
{
    using(var command = connection.CreateCommand())
    {
        var parameter = command.CreateParameter();
        parameter.ParameterName = "@answer";
        parameter.Value = 42;
        command.Parameters.Add(parameter);
        /// and so forth
    }
}

然后:

using(var connection = new OracleConnection())
{
    MyAgnosticDatabaseMethod(connection);
}
using(var connection = new SqlConnection())
{
    MyAgnosticDatabaseMethod(connection);
}

相关内容

最新更新