2012-05-23 75 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