ADO.Net数据库操作综合起来就是增删改查,而且这几个流程都是固定的。
查询:连接数据库-->打开记录集-->遍历记录集并获取记录内容
插入:连接数据库-->打开记录集-->插入数据库记录-->将记录保存到数据库
更新:连接数据库-->打开记录集-->遍历记录集并更新记录-->将记录保存到数据库
删除:连接数据库-->执行删除的SQL语句
将表的一行数据内容封装成一个数据记录类,该数据记录类实现如下接口:
public interface IDBOperability
{
void SetRecordData(IDBRecord dbRecord, Object oFlag);
void GetRecordData(IDBRecord dbRecord, Object oFlag);
Object PrimaryKey { get; set; }
}
需要做到快速,还需要一个小工具ADO.Net助手来帮忙根据SQL内容生成数据记录类,具体操作及使用请参考《如何使用ADO.Net助手生成C#数据库代码》。
使用ADO.Net助手辅助生产数据库代码。
一. 用ADO.Net助手生成数据库代码
SQL Server2005的建表语句如下:
CREATE TABLE [dbo].[tbl_Demo](
[ID] [int] IDENTITY(50,1) NOT NULL,
[Guid] [nvarchar](80) COLLATE Chinese_PRC_CI_AS NOT NULL,
[Name] [nvarchar](20) COLLATE Chinese_PRC_CI_AS NULL,
[Birthday] [datetime] NULL,
[Photo] [image] NULL,
CONSTRAINT [PK_tbl_Demo] PRIMARY KEY CLUSTERED
(
[Guid] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
用 ADO.Net助手生成的C#代码如下:
/*----------------------------------------------------------------------------------------------------------------
Version: CSAdonetCodeWriter 1.00
Time: 2012/12/4 19:47:03
SQL: SELECT * FROM Tbl_Demo
----------------------------------------------------------------------------------------------------------------*/
using System;
using System.Collections.Generic;
using System.Text;
namespace Database
{
[DBTableAttribute("Tbl_Demo", "Guid")]
public class Tbl_Demo : IDBOperability
{
#region AutoIncrement
private static readonly DBTableAttribute m_AutoIncrement = new DBTableAttribute("Tbl_Demo", "Guid", "Id");
public static DBTableAttribute AutoIncrement
{
get { return Tbl_Demo.m_AutoIncrement; }
}
#endregion
#region Field and Property
/// <summary>
/// 0 ID Int32
/// </summary>
protected Int32 m_ID;
/// <summary>
/// 0 ID Int32
/// </summary>
public Int32 ID
{
get
{
return m_ID;
}
set
{
m_ID = value;
}
}
/// <summary>
/// 1 Guid String
/// </summary>
protected String m_Guid;
/// <summary>
/// 1 Guid String
/// </summary>
public String Guid
{
get
{
return m_Guid;
}
set
{
m_Guid = value;
}
}
/// <summary>
/// 2 Name String
/// </summary>
protected String m_Name;
/// <summary>
/// 2 Name String
/// </summary>
public String Name
{
get
{
return m_Name;
}
set
{
m_Name = value;
}
}
/// <summary>
/// 3 Birthday DateTime
/// </summary>
protected DateTime? m_Birthday;
/// <summary>
/// 3 Birthday DateTime
/// </summary>
public DateTime? Birthday
{
get
{
return m_Birthday;
}
set
{
m_Birthday = value;
}
}
/// <summary>
/// 4 Photo Byte[]
/// </summary>
protected Byte[] m_Photo;
/// <summary>
/// 4 Photo Byte[]
/// </summary>
public Byte[] Photo
{
get
{
return m_Photo;
}
set
{
m_Photo = value;
}
}
#endregion
#region IDBOperability
/// <summary>
/// 1 Guid String
/// </summary>
Object IDBOperability.PrimaryKey
{
get
{
return this.Guid;
}
set
{
this.Guid = (String)value;
}
}
void IDBOperability.SetRecordData(IDBRecord dbRecord, Object oFlag)
{
IDBRecord x = dbRecord;
//x["ID"] = ID; // 0 Int32
x["Guid"] = Guid; // 1 String
x["Name"] = Name; // 2 String
x["Birthday"] = Birthday; // 3 DateTime
x["Photo"] = Photo; // 4 Byte[]
/*
//x[0] = ID; // ID Int32
x[1] = Guid; // Guid String
x[2] = Name; // Name String
x[3] = Birthday; // Birthday DateTime
x[4] = Photo; // Photo Byte[]
*/
}
void IDBOperability.GetRecordData(IDBRecord dbRecord, Object oFlag)
{
IDBRecord x = dbRecord;
ID = DBValue.Convert(x["ID"]); // 0 Int32
Guid = DBValue.Convert(x["Guid"]); // 1 String
Name = DBValue.Convert(x["Name"]); // 2 String
Birthday = DBValue.Convert(x["Birthday"]); // 3 DateTime
Photo = DBValue.Convert(x["Photo"]); // 4 Byte[]
/*
ID = DBValue.Convert(x[0]) // ID Int32
Guid = DBValue.Convert(x[1]) // Guid String
Name = DBValue.Convert(x[2]) // Name String
Birthday = DBValue.Convert(x[3]) // Birthday DateTime
Photo = DBValue.Convert(x[4]) // Photo Byte[]
*/
}
#endregion
}
}
二. 将生成的数据库代码和ADO.Net的封装类添加到工程引用中,然后编译整个项目解决方案(为后面的添加数据源做准备)
三. 拖主界面如下图
为一个DataGridView和五个按钮,DataGridView的DataSource属性进行添加项目数据源,选择数据源类型为对象,点击下一步,在选择数据对象界面选择刚才用ADO.Net助手生成的数据库类对象,点击完成按钮完成对数据源的添加。DataGridView的Columns属性各个列的HeadText修改为界面显示的列名。
四. 拖数据编辑对话框如下图
拖动一个BindingSource控件到界面中,对其DataSource属性用刚才和添加DataGridView数据源方式添加数据源。
设置TextBox中DataBindings的Text,DateTimePicker中DataBindings的Value和pictureBox中DataBindings的Image设置为添加的数据源各相对应的字段。
五. 编写相应的数据库代码
1. 连接数据库
定义数据库对象
IDBDatabase m_db;
public IDBDatabase Db
{
get { return m_db; }
set { m_db = value; }
}
初始化并连接
private void MainForm_Load(object sender, EventArgs e)
{
try
{
Settings cfg = Settings.Default;
Db = DBFactory.CreateDatabase(cfg.Connection);
if (Db == null)
{
throw new Exception("配置的Connection不正确或者未加载到数据库提供程序");
}
Db.ConnectionString = cfg.ConnectionString;
int nUpdateBatchSize = 1;
int.TryParse(cfg.UpdateBatchSize, out nUpdateBatchSize);
Db.DBSetCommandBuilder += delegate(Object s, DbCommandBuilder cmdBuilder)
{
cmdBuilder.QuotePrefix = cfg.QuotePrefix;
cmdBuilder.QuoteSuffix = cfg.QuoteSuffix;
cmdBuilder.DataAdapter.UpdateBatchSize = nUpdateBatchSize;
};
Db.Open();
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
Environment.Exit(-1);
}
button_Refresh.PerformClick();
}
定义记录对象
List<Tbl_Demo> m_DelDemos = new List<Tbl_Demo>();
public List<Tbl_Demo> DelDemos
{
get { return m_DelDemos; }
set { m_DelDemos = value; }
}
定义当前选中的记录
public Tbl_Demo CurDemo
{
get
{
return tblDemoBindingSource.Current as Tbl_Demo;
}
}
2. 查询
private void button_Refresh_Click(object sender, EventArgs e)
{
int nCount = Db.Count<Tbl_Demo>();
if (Demos.Capacity < nCount)
{
Demos.Capacity = nCount;
}
Db.Select(Demos);
tblDemoBindingSource.DataSource = Demos;
tblDemoBindingSource.ResetBindings(false);
}
3. 添加
private void button_New_Click(object sender, EventArgs e)
{
tblDemoBindingSource.AddNew();
using (TblDemoForm dlg = new TblDemoForm())
{
CurDemo.Guid = Guid.NewGuid().ToString();
CurDemo.Birthday = DateTime.Today;
dlg.TblDemoBindingSource.DataSource = tblDemoBindingSource.DataSource;
dlg.TblDemoBindingSource.Position = tblDemoBindingSource.Position;
if (DialogResult.OK == dlg.ShowDialog(this))
{
try
{
Db.Save(CurDemo);
CurDemo.ID = Db.Scalar(CurDemo, Tbl_Demo.AutoIncrement);
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}
else
{
tblDemoBindingSource.RemoveCurrent();
}
tblDemoBindingSource.ResetCurrentItem();
}
}
4. 编辑
private void button_Edit_Click(object sender, EventArgs e)
{
if (CurDemo == null)
{
return;
}
using (TblDemoForm dlg = new TblDemoForm())
{
dlg.TblDemoBindingSource.DataSource = tblDemoBindingSource.DataSource;
dlg.TblDemoBindingSource.Position = tblDemoBindingSource.Position;
if (DialogResult.OK == dlg.ShowDialog(this))
{
try
{
Db.Save(CurDemo);
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}
tblDemoBindingSource.ResetCurrentItem();
}
}
5. 删除
private void button_Del_Click(object sender, EventArgs e)
{
if (CurDemo == null)
{
return;
}
try
{
Db.Delete(CurDemo);
tblDemoBindingSource.RemoveCurrent();
MessageBox.Show("成功将数据从数据库中删除");
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}
调用存储过程
--SQL Server 2005 存储过程
Create Procedure [dbo].[usp_ProcedureTest]
@firstParam int,
@secondParam int Output,
@thirdParam datetime Output
As
BEGIN
-- 返回记录集的话最好是用下面语句关闭一些不必要的返回记录集
SET NOCOUNT ON;
DECLARE @Count int
SET @secondParam = @firstParam * 10
SELECT @thirdParam = getdate()
SELECT @Count = Count(*) FROM tbl_Demo
SELECT * FROM tbl_Demo
return @Count
END
调用代码:
private void button_Procedure_Click(object sender, EventArgs e)
{
try
{
DbCommand cmd = Db.CreateProcedureTCommand("usp_ProcedureTest");
int firstParam = 8;
cmd.Parameters["@firstParam"].Value = firstParam;
List<Tbl_Demo> lDemo = new List<Tbl_Demo>();
using (DbDataReader reader = cmd.ExecuteReader())
{
// 解析记录
DBHelper.GetRecordData(lDemo, reader, null);
// 用ExecuteReader执行存储过程的话要先关闭DataReader才能取各参数值
reader.Close();
}
int secondParam = (int)cmd.Parameters["@secondParam"].Value;
DateTime tm = (DateTime)cmd.Parameters["@thirdParam"].Value;
int nRet = (int)cmd.Parameters[0].Value;
string msg = string.Format("{0}*10={1}\n数据库时间是{2}\n有{3}条记录",
firstParam, secondParam, tm, nRet);
MessageBox.Show(msg);
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Demo中将数据信息配置在配置文件中,可以按配置文件的格式做相应修改即可以切换数据库,已经简单验证在ACCESS,SQLSERVER,MYSQL,ORACLE和SQLite均正常运行。
这里虽然说的winform的,但上述数据库增删查改流程在支持ADO.Net语言的程序中均适用。