我在2005年10月9日写的一篇文章“数据库小工具(C#)”中提到:
当时,对各个不同的数据库是分别实现这个“数据库小工具”的。
现在,让我们将这些独立的“小工具”整合在一起吧。
从上图中可以看到 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行)。
使用 DbProvid