16

我有一个 IDbConnection 实例,它可以是任何连接、Sql、OleDb 等。我想做一个通用包装器,这样我就可以向包装器发送一个连接并获得一组很好的方法以便于操作。我有一个 Query 方法,我希望它返回一个 DataTable,所以我可以这样做

IDataAdapter adapter = new OleDbDataAdapter();
adapter.SelectCommand = myCommand;
DataSet ds = new DataSet();
adapter.Fill(ds);

问题是我必须使用 OleDbAdapter 并且它不适用于 SQL,我真的不想编写“驱动程序特定”代码。有没有办法从我实例化的 IDbConnection 对象中获取 IDataAdapter 实例?我知道我可以创建一个命令

IDbCommand command = _connection.CreateCommand();

认为必须有一些简单的方法来对 IDataAdapter 执行相同操作是合乎逻辑的。

编辑:

using (var reader = command.ExecuteReader())
{
    var dataTable = new DataTable();
    dataTable.Load(reader);
}

嗯,不完全是我要求的,而是一个很好的解决方案。

4

2 回答 2

7

这是一个粗略的示例,说明如何使用反射获取适配器。

IDataAdapter GetAdapter(IDbConnection connection) {
    var assembly = connection.GetType().Assembly;
    var @namespace = connection.GetType().Namespace;    

    // Assumes the factory is in the same namespace
    var factoryType = assembly.GetTypes()
                        .Where (x => x.Namespace == @namespace)
                        .Where (x => x.IsSubclassOf(typeof(DbProviderFactory)))
                        .Single();

    // SqlClientFactory and OleDbFactory both have an Instance field.
    var instanceFieldInfo = factoryType.GetField("Instance", BindingFlags.Static | BindingFlags.Public);
    var factory = (DbProviderFactory) instanceFieldInfo.GetValue(null);

    return factory.CreateDataAdapter();
}
于 2012-05-23T17:06:04.633 回答
4

我有同样的问题。这就是我解决它的方法

private DataSet executeDataQuery(string query, string connection, string provider, out Exception ex) {
        DataSet ds = new DataSet();
        ex = null;
        DbProviderFactory dbFactory = DbProviderFactories.GetFactory(provider);
        IDbConnection dbConnection = dbFactory.CreateConnection();
        dbConnection.ConnectionString = connection;
        using (dbConnection) {
            try {
                IDbDataAdapter dbAdapter = dbFactory.CreateDataAdapter();
                IDbCommand dbCommand = dbConnection.CreateCommand();
                dbCommand.CommandText = query;
                dbCommand.CommandType = CommandType.Text;
                dbAdapter.SelectCommand = dbCommand;
                dbAdapter.Fill(ds);
            }
            catch (Exception exc) {
                ex = exc;
            }
            finally {
                if (dbConnection.State == ConnectionState.Open) {
                    dbConnection.Close();
                }
            }
        }
        return ds;
    }
于 2014-12-13T17:39:34.917 回答