C#成神之路<附加> C#数据库

1、数据库
定义:数据库只是一个信息的集合。关系数据库是一个信息的集合,这种数据库中的数据以某种方式和另一个数据关联。
DBMS(商业数据库管理系统):简化了与构建和使用关系数据库关联的任务。

(1)数据库的结构
关系数据库:通常是两个或两个以上数据库表的集合。
数据库表、字段和记录
数据库表:按行和列排列的数据库的结构。
数据库表中的每一行称为一个记录。
数据库表中的每一列称为一个字段。(类似于数据库的属性,每个字段用来存储特定数据项的值)
数据库表可能有0行或多行。如果表有0行,就说这个数据库表是空,不包含有用信息。数据库表一般至少有两个或多个字段。

数据规范化
数据规范化:从数据库中删除重复或者冗余数据的过程。

主键
表中存放独有值的字段称之为主键字段。
如果某个记录的一个字段中有一个独有值,我们就可以说表中每个记录都是独有的(因为有主键字段)。可以在不同的表中用这个主键字段引用另一个表中的信息。(这就是把这样的数据库成为关系数据库的原因:存储在数据库中的数据的表之间存在某种关系。)
数据库的关系:一对一,多对多,一对多等等。
无穷号:数据库表关系的讨论中的术语“多”的标准表示法。

外键
作为表中外键的字段必须和另一个表建立某种关系。

2、使用自己的数据库
商业数据库多种类型:Microsoft:Access,SQL Server。IBM:DB2,MySQL,Oracle。
本文以Access为基础介绍。

ADO.NET
C#与数据库交互方式的重要工具:ADO.NET。
ADO.NET:由两种基本元素构成:数据提供程序元素,数据集元素。
(1)数据提供程序
有几个类共同作为ADO.NET的数据提供程序。
OLE DB:外部数据源与Microsoft交互的桥梁。这种方法是一种双赢的方法。
如果使用其他数据库,可以查找器提供程序信息,绕过OLEDB提供程序,这样可以提供更好的性能。

(2)OLE连接对象
为了与数据库通信,必须先建立与数据库的连接。
要通过OLE DB来使用数据库,所以用OleDbConnection类提供我们需要与数据库通信的连通性。一旦实例化一个OleDbConnection对象,就用该对象通过OleDbConnection对象执行对数据库的命令。(执行大部分数据库操作的启动点)

I.OLE Command对象
OleDbCommand对象用来处理结构化查询语言(SQL)命令。
SQL是使用关系数据库的标准语言。

II.数据定义语言(DDL)
SQL包括一个语言子集,成为数据定义语言(DDL)。初次创建数据库时,使用DDL命令建立第一次创建数据库结构。
(用DDL创建一个数据库,向数据库中添加表,并且向数据库表中添加字段。定义了结构之后,用其他DDL命令在数据库中添加编辑,删除行。其他大部分SQL操作符用来操作已经位于数据库中的数据。)

III.OLE reader 对象
当用OleDbCommand对象从数据库中取得数据后,用一个OleDbReader对象来遍历SQL命令产生的数据,使得reader对象的输出最终产生所要浏览的数据。

(3)数据集

数据集类:提供了操作在数据库中所含数据的方式。数据集对象是泛型,因为他们不随数据库而变化,所以他们的使用不会因为底层数据库的变化而变化。
每个数据集可以与一个有列和行的DataTable对象相关联。从Datatable对象中可以构造一个DataView对象。DataView对象通常表示由SQL命令过滤的数据集。

3、使用SQL
目的:为了将其作为创建、管理和维护关系数据库的通用数据库语言。
(1)SELECT语句
可以用来从数据库中检索数据的特定子集,大多数查询都用SELECT语句进行初始化。
语法为:

SELECT fieldList FROM tablename

fieldList是一个希望从数据库中检索的字段列表。用逗号分隔。
tablename 存放信息的表
例子:

SELECT firstName,lastName FROM Friends

SQL关键字的惯例是大写字母。

SELECT * FROM tablename

该查询返回一个数据集,其中包含Friend表中每一行的所有字段数据……那是问题所在:该数据集包含数据库中的每一个人。

(2)WHERE语句
可以用WHERE谓词来过滤从数据库返回的数据集

SELECT firstName,lastName FROM Friends WHERE Zip=80120

将会返回一个数据集,其中包含住在邮政编码为80120的地区的人的所有姓名。
也可以像WHERE谓词应用基本条件运算符。

SELECT firstName,lastName FROM Friends WHERE Zip>46214 AND Zip<46254 

它允许生成拥有某种限制性的数据集。

(3)ORDER BY语句
ORDER BY语句允许将数据集重新组织成升序或降序。

SELECT * FROM Friends WHERE Zip=46214 ORDER BY lastName

将返回按照lastName字段的升序排列的数据集。如果想要按照降序排列的同一个列表。应使用:

SELECT * FROM Friends WHERE Zip=46214 ORDER BY lastName DESC

关键字DESC,变成降序排列。

(4)聚合
有些数据库操作是如此常见,SQL提供了称为聚合的方法来对数据库执行特定的计算。至少大多数数据库都支持如下列出的聚合:
AVG:返回选中字段的数值平均值。

SELECT AVG(Age)FROM Friend

COUNT:返回在选中字段中发现的项数。

SELECT COUNT(lastName) FROM Friend WHERE Status=1

指出表中有多少活动的人。

MIN:查找字段中的最小值。

SELECT MIN(Age) FROM Friend

MAX:查找字段中的最大值。

SELECET MAX(Age) FROM Friend

SUM:返回字段中值的和。

SELECT SUN(Status)FROM Friend

返回表中活动的人数。

(5)示例程序:编写自己的数据库
创建一个MDI程序。创建Access数据库,向该数据库添加表,以及添加、编辑和删除行数据。

OLE DB功能没有提供创建新数据库的能力。这里使用ADOX(标准ADO的一个扩展)来给我们创建新数据库的能力。
Visual Studio——>Project->Add Reference命令,选择COM选项卡,选择Microsoft ADO Ext.2.8 for DDL and Security reference选项。添加引用之后。向clsDB类提供CreateNewDB()方法。

  public int CreateNewDB(string name) { 
        int index;
        string newDB;

        try
        {
            if (name.Length == 0 && dbName.Length == 0)
            {
                return 0;
            }
            index = name.LastIndexOf(".");
            if (index == -1)
            {
                dbName += ".mdb";
                name = dbName;
            }
            combineName = Path.Combine(pathName, name);
            ADOX.CatalogClass myCat = new ADOX.CatalogClass();
            newDB = CONNECTSTRING + combineName + ";" + CONNECTSTRINGPART2;
            myCat.Create(newDB);
            myCat = null;

        }
        catch(Exception ex)
        { 
#if DEDBUG
    Mssage.Show("Error: "+ex.Message);
#elseif
     return 0;
        }
return 1;
        }

上述代码需要传递到方法中的数据库的新名称。该方法通过一个菜单项从frmMain中调用的
以上代码将路径名与数据库名称结合到一起了。文件路径默认是指可执行程序所位于的路径。
预处理程序触发MessageBox方法的代码。如果没有发生错误,那么选中的目录中就会出现一个扩展名为.mdb的空数据库。

privare void mnuNew_Click(Object sender,EventArgs e)
{
frmCreateDB myNewDB=new frmCreateDB(dbName);
myNewDB.ShowDialog();
}

在子窗体中,输入新数据库名称,点击Create New DB之后,执行

clsDB myDB=new clsDB(txtDBName.Text);
flag=myDB.CreateNewDB(txtDBName.Text);

(6)创建新表
关于ListView控件中删除出错项的一种方式:

private void lstFiledsToAdd_DoubleClick(object sender,EventArgs e)
{
ListView.SelectedIndexCollection indexes=lstFieldsToAdd.SelecteedIndices;

foreach(int index in indexes)
{
lstFieldsToAdd.Items[index].Remove();
}
}

双击listView当中的出错项就可以对出错项进行删除。

Add New Table按钮:

private voidbtnWrite_Click(object sender,EventArgs e)
{
int i,j;
int flag;
string sqlCommand;
string buff;
string temp;

try
{
clsDB myDB=new clsDB(dbName);
sqlCommand="CREATE TABLE "+txtTableName.Text+"(ID COUNTER, ";

for(i=0;i<lstFieldsToAdd.Items.Count;i++)
{
temp=" ";
for(j=0;j<lstFieldsToAdd.Items[i].SubItems.Count;j++)
{
buff=lstFieldToAdd.Items[i].SubItems[j].Text;
switch(j)
{
case 0://field name
sqlCommand+=buff+"";
break;

case 1://The field length
temp=buff;
break;

case 2:
if(buff.Equals("TEXT")==true)
{
sqlCommand+="TEXT("+TEMP+"),";
}
else
{
sqlCommand+=buff+",";
}
break;

}
}
}
i=sqlCommand.LastIndexOf(",");
sqlCommand=sqlCommand.SubString(0,sqlCommand.Length-2);
sqlCommand+=")";
flag=myDB.ProcessCommand(sqlCommand);
if(flag==1)
{
sqlCommand="CREATE INDEX idxID ON"+txtTableName.Text+"(ID)WITH PRIMARY";
flag=myDB.ProcessCommand(sqlCommand);
if(flag==1)
{
MessageBox.Show("Table create successfully");
}
}
else
{
MessageBox.Show("Failed to create table.","Process Error");
}
}
catch(Exception ex)
{
MessageBox.Show("Error:"+ex.Message);
}
}

DDL支持用CREATE TABLE语句创建数据库表。上述代码中,代码通过用户输入的信息构建CREATE TABLE命令。然而下面的代码行自动创建了一个名为ID的字段。他是一个自动递增(COUNTER)的Access变量:

sqlCommand="CREATE TABLE "+txtTableName.Text+"(ID COUNTER, ";

计数器类型的变量无非是一个整数数据类型,每次想表中添加一个新行时递增自身。该字段确保表种每一行是唯一的。
然后for循环遍历listview控件的内容以构建CREATE TEBLE命令。
注意,表中第一个字段使我们暗中放到字段列表中的。

flag=myDB.ProcessCommand(sqlCommand);

调用类clsDB中的cessCommand()方法来执行SQL命令以创建表。如果flag==1,那么一切正常。
下列语句:

if(flag==1)
{
sqlCommand="CREATE INDEX idxID ON"+txtTableName.Text+"(ID)WITH PRIMARY";
flag=myDB.ProcessCommand(sqlCommand);
if(flag==1)
{
MessageBox.Show("Table create successfully");
}
}

构建另一个SQL命令来创建新表的一个数据库索引,并且使用ID作为表的主键。创建该索引能够改善查询性能。
SQL命令都是由clsDB类的同一个方法处理的:
代码如下:

public int ProcessCommand(string sqlCommand)
{
int flag;
OleDbConnection myDB=new OleDbConnection();
OleDbCommand command;
connectString=CONNECTSTRING+dbName;

try
{
myDB.ConnectionString=connectionString;
myDB.Open();

command=new OleDbCommand(aqlCommand,myDB);
command.ExecuteNonQuery();
}
catch(Exception ex)
{
#if DEBUG
MessageBox.Show("Error: "+ex.Message);
#endif
flag=0;
}
finally
{
myDB.close();
}
return flag;
}

该段代码实例化名为myDB的OLE DB连接,以及一个名为command的OLE命令对象。常量CONNECTION的定义如下:

private const string CONNECTSTRING="Provider=Microsoft.Jet.OLEDB.4.0;Data source=";

该段代码将数据库定义为一个Access数据库。对于其他数据库,需要修改这个连接字符串。

myDB.Open();

command=new OleDbCommand(aqlCommand,myDB);
command.ExecuteNonQuery();

上述代码,打开数据库,并且实例化OleDbCommand对象。
当不要求SQL命令返回结果的时候,使用OLE DB ExecuteNonQuery()方法。

(7)向表中添加记录(INSERT INTO)
此处程序借用上文使用过的程序,并且对其进行修改。随机存储文件的程序。
需要对其进行必要的修改。代码如下(主要是对save按钮的修改)

private void btnSave_Click(object sender,EventArgs e)
{
int status;
int flag;
intg i;
string sqlCommand;
string[] colName=new string[MAXCOLUMNS];

clsDB myDB=new clsDB(dbName);
myDB.GetColumnInfo(colNames);

if(chkStatus.Checked==true)
status=1;
else
status=0;

//Build INSERT command
sqlCommand="INSERT INTO "+dbTableName+" (";
for(i=1;i>colNames.Length;i++)
{
if(colNames[i]==null)
break;
sqlCommand+=sqlName[i]+", ";
}
i=sqlCommand.LastIndexOf(",");
sqlCommand=sqlCommand.Substring(0,i)+")VALUES(";
//Now add the values;
sqlCommand+=txtFirstName.Text+"','"+
txtMI.Text+"','"+
txtLastName.Text+"','"+
status.ToString()+")";

flag=myDB.ProcessCommand(sqlCommand);
if(flag==1)
{
MessageBox.Show(Record added success);
}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值