Подтвердить что ты не робот

Активировать IDataAdapter из экземпляра IDbConnection

У меня есть экземпляр IDbConnection, который может быть любым соединением, Sql, OleDb и т.д. Я хочу создать общую оболочку, чтобы я мог просто отправить оболочку на соединение и получить хороший набор методов для легкого манипулирования. У меня есть метод запроса, я хочу, чтобы он возвращал DataTable, поэтому я могу сделать

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

Проблема в том, что я должен использовать OleDbAdapter, и он не будет работать для SQL, я действительно не хочу писать "специфичный для драйвера" код. Есть ли способ получить экземпляр IDataAdapter из моего экземпляра объекта IDbConnection? Я знаю, что могу создать команду, выполняющую

IDbCommand command = _connection.CreateCommand();

Логично думать, что должен быть какой-то простой способ сделать то же самое с IDataAdapter.

EDIT:

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

Ну, не совсем то, что я просил, но хорошее решение.

4b9b3361

Ответ 1

Вот приблизительный пример того, как вы могли бы получить адаптер, используя отражение.

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();
}

Ответ 2

У меня была та же проблема. Вот как я его решил

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;
    }