2012-05-23 5 views
13

Ich habe eine Instanz von IDbConnection, die jede Verbindung sein kann, Sql, OleDb, etc. Ich möchte eine generische Wrapper machen, damit ich nur den Wrapper eine Verbindung und ein schönes Set bekommen kann von Methoden zur einfachen Manipulation. ich eine Query-Methode haben, möchte ich es ein Datatable zurück, so kann ichInstanziieren IDataAdapter von Instanz IDbConnection

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

Das Problem tun ist, ich OleDbAdapter verwenden, und es wäre für SQL nicht, ich will nicht wirklich schreibe "treiberspezifischen" Code. Kann ich eine IDataAdapter-Instanz von meinem instanziierten IDbConnection-Objekt abrufen? Ich weiß, ich kann einen Befehl erstellen tun

IDbCommand command = _connection.CreateCommand(); 

Es ist nur logisch zu denken, müssen einige einfache Möglichkeit, das gleiche mit einem IDataAdapter zu tun.

EDIT:

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

Also, nicht genau das, was ich gefragt, sondern eine schöne Lösung.

+1

Wenn Sie generischen ADO.Net-Code schreiben, werden Sie Factory-Methoden haben, die die Provider-Eigenschaft der Verbindungszeichenfolge anzeigen müssen. Wenn Sie dieses Stück haben, können Sie [DbProviderFactory.CreateDataAdapter] (http://msdn.microsoft.com/en-us/library/system.data.common.dbproviderfactory.createdataadapter.aspx) – mdisibio

+0

+1 für die Freigabe der Lösung verwenden mit dem IDataReader. Wir haben ein benutzerdefiniertes Framework, das für die Behandlung von Datenbankverbindungen, Transaktionen usw. verwendet wird, unterstützt jedoch (noch) keine Datenadapter. Mit IDataReader können wir dieses Framework jedoch verwenden, ohne es erweitern/modifizieren zu müssen. –

+0

Ich habe mir die Freiheit genommen, Ihre Frage zu bearbeiten, um die Anweisung 'using' hinzuzufügen, die den Leser automatisch schließt (http://stackoverflow.com/a/2157331/808151). –

Antwort

7

Hier ist ein grobes Beispiel, wie Sie den Adapter mit Reflektion bekommen können.

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

Ich hatte das gleiche Problem. Dies ist, wie ich es löste

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

sollten Sie die Verwendung um die IDbConnection setzen dbConnection = dbFactory.CreateConnection(); – BlackICE

Verwandte Themen