2012-05-23 74 views
13

我有一個IDbConnection的實例,它可以是任何連接,Sql,OleDb等。 我想製作一個通用包裝器,這樣我就可以發送包裝器一個連接並獲得一個很好的集合易於操作的方法。 我有一個查詢方法,我希望它返回一個DataTable,所以我可以做從IDbConnection實例實例化IDataAdapter

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

那麼不正是我要的但很好的解決方案。

+1

當您編寫通用的ADO.Net代碼時,在某些時候,您將需要Factory方法來查看連接字符串的Provider屬性。如果您擁有該部分,則可以使用[DbProviderFactory.CreateDataAdapter](http://msdn.microsoft.com/zh-cn/library/system.data.common.dbproviderfactory.createdataadapter.aspx) – mdisibio

+0

+1來共享解決方案與IDataReader。我們有一個用於處理數據庫連接,事務處理等的自定義框架,但它還不支持數據適配器。通過使用IDataReader,我們可以使用該框架而不必擴展/修改它。 –

+0

我冒昧地編輯你的問題,添加'using'語句[自動關閉閱讀器](http://stackoverflow.com/a/2157331/808151)。 –

回答

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

你應該在IDbConnection周圍使用dbConnection = dbFactory.CreateConnection(); – BlackICE