Ответ 1
DbProviderFactory.CreateDataAdapter *
Также вы можете получить все зарегистрированные DbProviders через DbProviderFactories класс.
* Я думаю, что это неправильное место для этого метода.
Я хочу создать уровень доступа к данным, который работает с любым поставщиком данных.
Я знаю, что можно создать DbCommand
с помощью метода factory, доступного в соединении.
objDbCon.CreateCommand();
Однако я не мог найти ничего для создания DbDataAdapter
. Это ошибка в ADO.NET или что?
DbProviderFactory.CreateDataAdapter *
Также вы можете получить все зарегистрированные DbProviders через DbProviderFactories класс.
* Я думаю, что это неправильное место для этого метода.
Как и для .NET 4.5, при написании независимого от поставщика кода теперь вы можете использовать перегрузку DbProviderFactories.GetFactory
, которая принимает DbConnection
, чтобы получить правильный провайдер factory, из которого вы можете создать адаптер данных.
Пример:
DbDataAdapter CreateDataAdapter(DbConnection connection)
{
return DbProviderFactories.GetFactory(connection).CreateDataAdapter();
}
Кажется, что кто-то из команды ADO.NET прочитал комментарий Яна Бойда к его ответу...:)
Хотя на это хорошо ответил Сергей, мне потребовалось немного времени, чтобы перевести его на собственные нужды. Таким образом, я понял, что если у вас есть DbConnection, но знаете, что вы используете SqlClient под капотом, ваш код будет выглядеть примерно так:
DbDataAdapter da = DbProviderFactories.GetFactory("System.Data.SqlClient").CreateDataAdapter();
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;
}
Учитывая, что вы не знаете тип соединения, которое вам дано,.NET не дает хорошего способа решить проблему. Здесь мы используем:
/// <summary>
/// Construct a DataAdapater based on the type of DbConnection passed.
/// You can call connection.CreateCommand() to create a DbCommand object,
/// but there 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 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;
}
Вы можете использовать другой способ для получения данных в DataTable без DbDataAdapter.
Вот мой код
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;