我想創建一個適用於任何數據提供者的數據訪問層。如何在給定DbCommand或DbConnection的情況下創建DbDataAdapter?
我知道可以使用連接上可用的工廠方法創建一個DbCommand
。
objDbCon.CreateCommand();
但是,我找不到任何東西來創建DbDataAdapter
。這是ADO.NET中的錯誤還是什麼?
我想創建一個適用於任何數據提供者的數據訪問層。如何在給定DbCommand或DbConnection的情況下創建DbDataAdapter?
我知道可以使用連接上可用的工廠方法創建一個DbCommand
。
objDbCon.CreateCommand();
但是,我找不到任何東西來創建DbDataAdapter
。這是ADO.NET中的錯誤還是什麼?
DbProviderFactory.CreateDataAdapter *
您也可以通過DbProviderFactories類獲得已註冊的DbProviders。
*我認爲這是一個錯誤的地方這種方法。
儘管謝爾蓋回答得很好,但我花了一段時間纔將其翻譯成我自己的需求。所以我的理解是,如果你有一個的DbConnection但知道你用引擎蓋下的SqlClient你的代碼看起來是這樣的:
DbDataAdapter da = DbProviderFactories.GetFactory("System.Data.SqlClient").CreateDataAdapter();
既然你不知道你給出的連接類型。 NET沒有提供解決問題的好方法。下面是我們使用:
/// <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;
}
這將工作,但我不認爲它的最佳途徑:) – Karim 2012-09-10 18:43:44
@卡里姆我***愛***更好的解決方案。我會想'connection.CreateAdapater'或'DbProviderFactories.GetFactory(connection)',或'DbProviderFactories.GetFactory(typeof(connection))',或*** *** ***。 – 2012-09-11 19:13:09
請注意,這似乎是ADO.NET團隊*從.NET 4.5實際實現的。 – 2015-04-13 19:38:18
由於.NET 4.5,編寫提供獨立的代碼時,你現在可以使用DbProviderFactories.GetFactory
重載接受DbConnection
以獲得正確的供應商工廠,從中可以再創建一個數據適配器。
例子:
DbDataAdapter CreateDataAdapter(DbConnection connection)
{
return DbProviderFactories.GetFactory(connection).CreateDataAdapter();
}
似乎有人在ADO.NET團隊閱讀他的答案伊恩·博伊德評論... :)
我只是谷歌搜索這個問題的解決方案;一年之後。我的硬編碼的情況下不處理'SqlCeConnection'和'SqlCeDataAdapter'。而且由於這是共享代碼,我不想強制每個客戶端在他們甚至不使用它時安裝'SQL Server CE'。榮譽給你找到本來應該需要的東西! – 2013-09-30 00:33:41
它是否在** GetFactory(連接)**僅在**。net 4.5 **?中工作,因爲[MSDN](https://msdn.microsoft.com/zh-cn/library/hh323136 (v = vs.100).aspx)表示它支持** 4.0 **,但在我的情況下不是。 – mayank 2015-05-13 05:38:39
你可以用另一種方式來獲取數據到數據表沒有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;
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;
}
給定一個'DbCommand'或'DbConnection',你如何得到相應的'DbProviderFactory'? – 2015-04-14 15:11:21
@伊恩博伊德http://msdn.microsoft.com/en-us/library/hh323136.aspx – 2015-04-14 21:31:51