数据库小工具整合版
我在2005年10月9日寫的一篇文章“數據庫小工具(C#)”中提到:
在編寫有關數據庫方面的C#程序時,經常需要知道數據庫的表中各字段的以下信息:1. 用于OracleParameter(或SqlParameter,...)中的字段和屬性的數據庫特定的數據類型。
2. 其對應的.NET數據類型。
當時,對各個不同的數據庫是分別實現這個“數據庫小工具”的。
現在,讓我們將這些獨立的“小工具”整合在一起吧。
從上圖中可以看到 Odbc、OleDb、Oracle、SQL Server、SQL Server Mobile Edition、SQL Server Compact Edition、SQLite、MySql 等數據庫都已經整合在同一個程序中了。
上圖顯示執行一條 SQL 語句后的結果。
上圖顯示出數據庫中的表的結構。
好了,我們來看源程序吧:
using System; using System.IO; using System.Data; using System.Data.Common; using System.Windows.Forms;namespace Skyiv.Ben.DbTools {public partial class MainForm : Form{public MainForm(){InitializeComponent();}private void MainForm_Load(object sender, EventArgs e){try{tbxDsn.Text = "Data Source=:memory:";tbxSql.Text = "select sqlite_version()";var table = DbProviderFactories.GetFactoryClasses();lbxDbProvider.ValueMember = "InvariantName";lbxDbProvider.DataSource = table;dgvMain.DataSource = table;lbxDbProvider.SelectedValue = "System.Data.SQLite";}catch (Exception ex){tbxMessage.AppendText(Pub.GetMessage(ex));}}private void btnSubmit_Click(object sender, EventArgs e){btnSubmit.Enabled = false;try{tbxMessage.Clear();var factory = DbProviderFactories.GetFactory(lbxDbProvider.SelectedValue.ToString());using (var conn = factory.CreateConnection()){conn.ConnectionString = tbxDsn.Text;conn.Open();tbxMessage.AppendLine("Client Version: [{0}]", Pub.GetClientVersion(Path.GetFileNameWithoutExtension(factory.ToString())));tbxMessage.AppendLine("Server Version: [{0}]", conn.ServerVersion);var sql = tbxSql.Text.Trim();if (sql.Length != 0){var comm = conn.CreateCommand();comm.CommandText = sql;var isQuery = IsQuery(sql);var rows = int.MinValue;if (!isQuery) rows = comm.ExecuteNonQuery();else if (chkStruct.Checked) dgvMain.DataSource = RunQueryTableStruct(comm);else dgvMain.DataSource = RunQueryTableData(factory, comm);tbxMessage.AppendText("運行 SQL 語句完畢(" + (!isQuery ? "非查詢" : (chkStruct.Checked ? "表結構" : "查詢")) + ")");if (rows >= 0) tbxMessage.AppendText(",受影響的行數: " + rows.ToString("N0"));}else tbxMessage.AppendText("完成");}}catch (Exception ex){tbxMessage.AppendText(Pub.GetMessage(ex));}btnSubmit.Enabled = true;}DataView RunQueryTableStruct(DbCommand comm){using (var r = comm.ExecuteReader(CommandBehavior.KeyInfo)){return r.GetSchemaTable().DefaultView;}}DataView RunQueryTableData(DbProviderFactory factory, DbCommand comm){var da = factory.CreateDataAdapter();da.SelectCommand = comm;var ds = new DataSet();da.Fill(ds);return ds.Tables[0].DefaultView;}bool IsQuery(string sql){return sql.ToUpper().StartsWith("SELECT");}} }這個程序主要使用 System.Data.Common 命名空間中的類來進行工作 。
在 MainForm_Load 方法(第16到32行)中使用 DbProviderFactories 的靜態方法 GetFactoryClasses 獲得在本機中實現 DbProviderFactories 的所有已安裝提供程序的信息(第22行),然后再將其綁定到程序主界面的 ListBox (第24行) 和 DataGridView (第25行) 控件上。這樣,這兩個控件就會聯動了。
點擊“執行”按鈕,就會調用 btnSubmit_Click 方法(第34到68行)。在該方法中:
- 使用 DbProviderFactories 類的靜態方法 GetFactory 獲得一個 DbProviderFactory (第40行)。
- 使用 DbProviderFactory 類的 CreateConnection 方法創建一個 DbConnection (第41行)。
- 使用 DbConnection 類的 Open 方法打開數據庫連接(第44行)。
- 使用 DbConnection 類的 CreateCommand 方法創建一個 DbCommand (第50行)。
- 如果要執行的 SQL 語句不是 SELECT 語句,則調用 DbCommand 類的 ExecuteNonQuery 方法執行該 SQL 語句(第54行)。
- 否則,如果程序主界面中的“結構”復選框被選中,就調用 RunQueryTableStruct 方法獲得數據庫中的表的結構(第55行)。
- 否則,就調用 RunQueryTableData 方法獲得數據庫中的表的數據(第56行)。
第70到76行的 RunQueryTableStruct 方法使用 DbCommand 類的 ExecuteReader 方法(使用 CommandBehavior.KeyInfo 參數)獲得一個 DbDataReader (第72行),然后調用 DbDataReader 類的 GetSchemaTable 方法來獲得數據庫中的表的各列的元數據(第74行)。
第78到85行的 RunQueryTableData 方法使用 DbProviderFactory 類的 CreateDataAdapter 方法創建一個 DbDataAdapter (第80行),然后使用 DbDataAdapter 類的 Fill 方法來填充 DataSet (第83行),最后返回該 DataSet 的 Tables 屬性中的第一個 DataTabe 的 DefaultView (第84行)。
該程序中的靜態類 Pub 類提供一些輔助的靜態方法:
using System; using System.Text; using System.Windows.Forms; using System.Reflection;namespace Skyiv.Ben.DbTools {static class Pub{public static string GetMessage(Exception ex){var sb = new StringBuilder();for (sb.Append("錯誤: "); ex != null; ex = ex.InnerException){sb.AppendFormat("[{0}]: ", ex.GetType());sb.AppendLine(ex.Message);}return sb.ToString();}public static void AppendLine(this TextBoxBase tbx, string fmt, params object[] args){tbx.AppendText(string.Format(fmt, args) + Environment.NewLine);}public static Version GetClientVersion(string name){foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) if (name == a.GetName().Name) return a.GetName().Version;return null;}} }最后,完整的源程序可以到 http://bitbucket.org/ben.skyiv/dbtools/downloads/ 頁面下載。
也可以使用 hg clone http://bitbucket.org/ben.skyiv/dbtools/ 命令下載。
關于 hg ,請參閱 Mercurial 備忘錄。
總結
- 上一篇: WAMP配置过程
- 下一篇: 10个可以简化开发过程的MySQL工具