2010-08-15 10 views

Antwort

10

DbProviderFactory.CreateDataAdapter *

Sie können auch alle registrierten DbProviders über DbProviderFactories Klasse erhalten.

* Ich denke, das ist ein falscher Ort für diese Methode.

+2

Bei einer 'DbCommand' oder' DbConnection', wie bekommt man die entsprechende 'DbProviderFactory'? –

+0

@Ian Boyd http://msdn.microsoft.com/en-us/library/hh323136.aspx –

5

Obwohl dies von Sergey gut beantwortet wurde, brauchte ich eine Weile, um es für meine eigenen Bedürfnisse zu übersetzen. So war mein Verständnis, dass, wenn Sie einen DbConnection hatte aber wussten Sie eine SqlClient unter der Haube wurden unter Verwendung von Code würde in etwa so aussehen:

DbDataAdapter da = DbProviderFactories.GetFactory("System.Data.SqlClient").CreateDataAdapter(); 
1

Vorausgesetzt, dass Sie nicht wissen, die Art der Verbindung, die Sie gegeben sind. NET bietet keine gute Möglichkeit, das Problem zu lösen. Hier ist, was wir verwenden:

/// <summary> 
/// Construct a DataAdapater based on the type of DbConnection passed. 
/// You can call connection.CreateCommand() to create a DbCommand object, 
/// but there's no corresponding connection.CreateDataAdapter() method. 
/// </summary> 
/// <param name="connection"></param> 
/// <exception>Throws Exception if the connection is not of a known type.</exception> 
/// <returns></returns> 
public static DbDataAdapter CreateDataAdapter(DbConnection connection) 
{ 
    //Note: Any code is released into the public domain. No attribution required. 

    DbDataAdapter adapter; //we can't construct an adapter directly 
     //So let's run around the block 3 times, before potentially crashing 

    if (connection is System.Data.SqlClient.SqlConnection) 
     adapter = new System.Data.SqlClient.SqlDataAdapter(); 
    else if (connection is System.Data.OleDb.OleDbConnection) 
     adapter = new System.Data.OleDb.OleDbDataAdapter(); 
    else if (connection is System.Data.Odbc.OdbcConnection) 
     adapter = new System.Data.Odbc.OdbcDataAdapter(); 
    else if (connection is System.Data.SqlServerCe.SqlCeConnection) 
     adapter = new System.Data.SqlServerCe.SqlCeDataAdapter(); 
    else if (connection is Oracle.ManagedDataAccess.Client.OracleConnection) 
     adapter = new Oracle.ManagedDataAccess.Client.OracleDataAdapter(); 
    else if (connection is Oracle.DataAccess.Client.OracleConnection) 
     adapter = new Oracle.DataAccess.Client.OracleDataAdapter(); 
    else if (connection is IBM.Data.DB2.DB2Connection) 
     adapter = new IBM.Data.DB2.DB2DataAdapter(); 
    //TODO: Add more DbConnection kinds as they become invented 
    else 
    { 
     throw new Exception("[CreateDataAdapter] Unknown DbConnection type: " + connection.GetType().FullName); 
    } 

    return adapter; 
} 
+1

das wird funktionieren, aber ich denke nicht, es ist der beste Weg, es zu tun :) – Karim

+2

@Karim ich habe *** Liebe *** eine bessere Lösung. Ich hätte gedacht 'connection.CreateAdapater' oder' DbProviderFactories.GetFactory (Verbindung) ', oder' DbProviderFactories.GetFactory (typeof (Verbindung)) ', oder *** etwas ***. –

+0

Beachten Sie, dass dies scheint, was das ADO.NET-Team * ab .NET 4.5 tatsächlich implementiert hat. –

15

Ab .NET 4.5, wenn Provider unabhängigen Code zu schreiben, können Sie jetzt die DbProviderFactories.GetFactory Überlastung, die eine DbConnection nimmt den richtigen Anbieter Fabrik zu erhalten, von dem Sie eine dann erstellen Datenadapter.

Beispiel:

DbDataAdapter CreateDataAdapter(DbConnection connection) 
{ 
    return DbProviderFactories.GetFactory(connection).CreateDataAdapter(); 
} 

Es scheint jemand auf dem ADO.NET-Team auf seine Antwort Ian Boyd Kommentar lesen ... :)

+2

Ich googelte nur für die Lösung dieses Problems; ein Jahr später. Meine hartcodierten Fälle behandeln 'SqlCeConnection' und' SqlCeDataAdapter' nicht. Und da dies ein gemeinsamer Code ist, möchte ich nicht jeden Client zwingen, "SQL Server CE" zu installieren, wenn sie ihn nicht einmal benutzen. Ein großes Lob an Sie, dass Sie herausgefunden haben, was eigentlich nötig war! –

+0

Ist es irgendwo geschrieben, wo das ** GetFactory (Verbindung) ** funktioniert nur in ** .net 4.5 ** ?, weil [MSDN] (https://msdn.microsoft.com/en-us/library/hh323136 (v = vs.100) .aspx) sagt, dass es in ** 4.0 ** unterstützt, aber in meinem Fall ist es nicht. – mayank

0

Sie eine andere Art und Weise können Sie Daten in Datentabelle erhalten ohne DbDataAdapter.

Hier ist mein Code

   DataTable dt = new DataTable(); 
       using (IDataReader dr = com.ExecuteReader()) 
       { 
        if (dr.FieldCount > 0) 
        { 
         for (int i = 0; i < dr.FieldCount; i++) 
         { 
          DataColumn dc = new DataColumn(dr.GetName(i), dr.GetFieldType(i)); 
          dt.Columns.Add(dc); 
         } 
         object[] rowobject = new object[dr.FieldCount]; 
         while (dr.Read()) 
         { 
          dr.GetValues(rowobject); 
          dt.LoadDataRow(rowobject, true); 
         } 
        } 
       } 
       return dt; 
2
private static DbDataAdapter CreateDataAdapter(DbCommand cmd) 
{ 
    DbDataAdapter adapter; 

    /* 
    * DbProviderFactories.GetFactory(DbConnection connection) seams buggy 
    * (.NET Framework too old?) 
    * this is a workaround 
    */ 
    string name_space = cmd.Connection.GetType().Namespace; 
    DbProviderFactory factory = DbProviderFactories.GetFactory(name_space); 
    adapter = factory.CreateDataAdapter(); 
    adapter.SelectCommand = cmd; 
    return adapter; 
} 
Verwandte Themen