.NET通用数据库访问组件SQL Artisan应用简介文档(doc)
下载对应的DOC文档
下载文档相关事例代码(包含了Web和Win应用)
1. 概述
SQL Artisan是由C#编写的一款通用数据库组件;组件提供O/R M和SQL对象操作两种模式来操作数据库。通过该组件的功能开发人员可以灵活、高效地编写数据库访问代码。些文档是用于描述SQL Artisan功能和使用过程,方便开发人员快速地了解SQL Artisan组件的功能并应用在实际开发中。
2. 应用结构图
3. 使用配置
组件提供配置文件的方式来配置项目所使用的数据处理容器;配置的信息主要包括数据库操作类型、数据连接字符串和O/R M映射的程序。
配置方式如下:
<configSections>
<section name="dataconfig" type="HFSoft.Data.DataConfigSectionHandler, HFSoft.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</configSections>
<dataconfig>
<DriverType value="HFSoft.Data.SqlDriver, HFSoft.Data, Version=1.0.0.0, Culure=neutral, PublicKeyToken=null"/>
<ConnectionString value="data source=.;initial catalog=northwind;user id=sa;pwd=;"/>
<MappingAssemblys>
<Assembly value="NorthWind.Entitys"/>
</MappingAssemblys>
</dataconfig>
n DriverType
用于描述数据处理容器用于处理那种数据库;组件默认提供了三种类型:
SqlDriver(MSSQL数据库)
OracleDriver(Oracle数据库)
OledbAccess(MSAccess数据库)
对于组件不提供的数据处理对象,用户可以通过IDriver接口来实现新的数据库处理对象。
n ConnectinString
用于描述数据处理容器相关数据库的连接字符串。
n MappingAssemblys
用于描述映射的程序集,根据情况可以配置多个映射的程序集;如果没有映射程序集时可以不需要此项标记。
当在操作配置的数据处理容器时相关容器会自动加载映射的程序信息。
可以通过以下方式来获取配置的数据处理容器对象:
IDataSession session = HFSoft.Data.MappingContainer.ConfigContainer.OpenSession()
4. 对象映射
4.1. 表结构映射
组件提供了Table类型和FieldAdapter类型来反映数据库的结构信息。开发人员可以通过这两种类型把数据库的结构信息反映到程序中。组件提供的数据操作对象通过操作Table和FieldAdapter对象把数据反映到数据库中。
n Table
用于描述数据库中的表,该类型提供INNER、LEFT和RIGHT方法创建新的关联表信息。
n FieldAdapter
用于描述数据库表中的字段。
有以下派生类:DateTimeField、NumberField、StringField、BooleanField、BytesField、TextField、GuidField和ObjectField;不同类型实现了不同的运算符和方法,用于更新相关字段信息和条件比较运算。
4.2. 对象映射
这种映射方式是通过一个XML描述文件把数据表和程序的某一对象类型关联起来;组件通过操作相应对象后把操作的结果反映到数据库中。对象类型的映射成员必须是公共可读写属性。为了让描述文件在组件加载程序集时同时加载,描述文件必须以嵌入资源的方式编译到程序集中。
XML描述文件:
<?xml version="1.0" encoding="utf-8" ?>
<class name="Northwind.Entitys.Orders,Northwind.Entitys" table="Orders">
<id name="OrderID" column="OrderID" />
<property name="CustomerID" column="CustomerID"/>
…………
<relation name="Customer" type=" …" entitytype="… " relationfield="…"/>
</class>
n 表映射
<class name="…" table="…">
name
对象类型[类全称,程序集]
table
对象类型对应的表名称
n 主索引字段映射
<id name="…" column="…" [value=”….”] />
name
对象类型的属性名称
column
表字段名
value
可选项,值由数据库提供时可描述此项。
value=”SELECT @@IDENTITY,true”
表示记录添中后获取相关值。
value=”select newid();false”表示添加记录前获取相关值。
n 其他字段映射
<property name="…" column="…"/>
name
对象类型的属性名称
column
表字段名
n 关联映射
<relation name="…" type=" …" entitytype="… " relationfield="…"/>
name
对象类型的属性名称
type
关系描述类型[类全称,程序集];该类型必须实现了HFSoft.Data.IRelation接口,组件实现该接口的类型有Parent,Childs;这两个类型只支持关联获取并不支持关联更新。Parent用开描述单一实体类型的父信息,Childs是用开描述集合类型(IList接口)的子信息。
entitytype
关联对象类型[类全称,程序集]
relationfield
用于描述关联的字段名,如果两个表关联字段不一致时可通过以下方式描述
relationfield=”本表字段-关联表字段”
当关联字段一致时
relationfield=”字段名”
5. 数据操作接口
组件提供相关的数据访问接口来访问数据库,这些接口分别可以对象数据库进行查询、添加、修改和删除操作。
5.1. IQuery
数据查询接口,通过此接口可以对表的数据进行查询和统计操作;IQuery同时也支持关联表查询。
接口成员和方法:
n Expressions.Table Table
获取或设置查询的表对象,可以通过表对象的方法来创建关联表查询。
n IDataSession Session
获取或设置查询对象所在数据处理容器。
n IExpression Expreesion
获取或设置查询数据的条件表达式,可以通过字段对象的运算符比较产生。
n FieldAdapter[] Selects
设置查询的字段对象列表,可以通过聚合函数、字段对象运算和函数套用的方式来产生字段对象。
n FieldAdapter[] OrderBy
设置查询排序的字段对象列表,FieldAdapter类型提供ASC和DESC属性提供了相应的排序方式。
n FieldAdapter[] GroupBy
设置查询数据分组的字段对象列表。
n int Execute()
执行查询并返回受影响的行数。
n System.Data.DataSet ExecuteDataSet()
执行查询并返回DataSet对象。
创建使用查询接口:
//创建查询对象
IQuery query = session.CreateQuery(
Orders.TBL.INNER(Customers.TBL,Customers._CustomerID)
& Orders.TBL.INNER(Employees.TBL,Employees._EmployeeID)
);
//设置查询的字段信息
query.Selects = new FieldAdapter[]{
Orders._ALL,
Customers._CompanyName,
(Employees._FirstName +Employees._LastName).As("EmployeeName")
};
//设置查询的排序信息
query.OrderBy = new FieldAdapter[]{Orders._OrderDate.ASC};
//设置查询的条件
Expression exp = new Expression();
if(DroCustomers.SelectedItem.Value !="")
{
exp &= Orders._CustomerID.At(Orders.TBL) == DroCustomers.SelectedValue;
}
if(DroEmployees.SelectedItem.Value != "")
{
exp &= Orders._EmployeeID.At(Orders.TBL) == int.Parse(DroEmployees.SelectedValue);
}
if(txtOrderDate_Begin.DateValue !=null && txtOrderDate_Begin.DateValue !="" )
{
exp &= Orders._OrderDate >= DateTime.Parse(txtOrderDate_Begin.DateValue);
}
if(txtOrderDate_End.DateValue !=null && txtOrderDate_End.DateValue!="")
{
exp &= Orders._OrderDate <= DateTime.Parse(txtOrderDate_End.DateValue);
}
query.Expreesion = exp;
session.Open();
System.Data.DataSet ds = query.ExecuteDataSet();
5.2. IInsert
数据添加接口,通过此接口可以对数据表进行数据添加操作。
接口成员和方法:
n FieldValue[] Fields
设置需要更新的字段信息,可以通过FieldAdapter派生类型的Set方法获取FieldValue对象。
n HFSoft.Data.Expressions.Table
设置需要操作的表对象。
n IDataSession Session
设置接口操作所在的数据处理容器。
n public int Execute()
创建使用数据添加接口:
//添加数据
private void Save()
{
using(IDataSession session = MappingContainer.ConfigContainer.OpenSession())
{
IInsert insert = session.CreateInsert(Employees.TBL);
insert.Fields = GetFieldValues();
session.Open();
insert.Execute();
}
}
//获取更新字段信息
private FieldValue[] GetFieldValues()
{
return new FieldValue[]{
Employees._Address.Set(this.editAddress.Text),
Employees._BirthDate.Set(DateTime.Parse(editBirthDate.DateValue)),
Employees._HireDate.Set(DateTime.Parse(editHireDate.DateValue)),
Employees._City.Set(editCity.Text),
Employees._Country.Set(editCountry.Text),
Employees._Extension.Set(editExtension.Text),
Employees._FirstName.Set(editFirstName.Text),
Employees._LastName.Set(editLastName.Text),
Employees._Notes.Set(editNotes.Text),
Employees._PostalCode.Set(editPostalCode.Text),
Employees._Region.Set(editRegion.Text),
Employees._ReportsTo.Set(int.Parse(editReportsTo.Text)),
Employees._Title.Set(editTitle.Text),
Employees._TitleOfCourtesy.Set(editTitleOfCourtesy.Text)
};
}
5.3. IUpdate
数据更新接口,通过此接口可以对数据表的数据进行更新操作。
接口成员和方法:
n Expressions.Table Table
设置操作的表对象
n FieldValue[] Fields
设置需要更新的字段信息,可以通过FieldAdapter派生类型的Set方法获取FieldValue对象。
n Expressions.Expression Expreesion
设置更新数据时的条件表达式,可以通过字段对象的运算符比较产生。
n IDataSession Session
n int Execute();
创建使用数据更新接口:
//更新数据
private void Update()
{
using(IDataSession session = MappingContainer.ConfigContainer.OpenSession())
{
IUpdate update = session.CreateUpdate(Employees.TBL);
update.Fields = GetFieldValues();
update.Expreesion = Employees._EmployeeID == int.Parse(EmployeeID);
session.Open();
update.Execute();
}
}
//获取更新字段信息
private FieldValue[] GetFieldValues()
{
return new FieldValue[]{
Employees._Address.Set(this.editAddress.Text),
Employees._BirthDate.Set(DateTime.Parse(editBirthDate.DateValue)),
Employees._HireDate.Set(DateTime.Parse(editHireDate.DateValue)),
Employees._City.Set(editCity.Text),
Employees._Country.Set(editCountry.Text),
Employees._Extension.Set(editExtension.Text),
Employees._FirstName.Set(editFirstName.Text),
Employees._LastName.Set(editLastName.Text),
Employees._Notes.Set(editNotes.Text),
Employees._PostalCode.Set(editPostalCode.Text),
Employees._Region.Set(editRegion.Text),
Employees._ReportsTo.Set(int.Parse(editReportsTo.Text)),
Employees._Title.Set(editTitle.Text),
Employees._TitleOfCourtesy.Set(editTitleOfCourtesy.Text)
};
}
5.4. IDelete
数据删除接口,通过些接口对表进行数据删除操作。
接口成员和方法:
n Expressions.Table Table
设置删除表对象
n IDataSession Session
设置删除对象运行的数据处理容器。
n Expressions.Expression Expreesion
设置删除数据时条件表达式, 可以通过字段对象的运算符比较产生。
n int Execute();
执行删除操作并返回受影响的行数
创建使用数据删除接口:
using(IDataSession session = HFSoft.Data.MappingContainer.ConfigContainer.OpenSession())
{
IDelete del = session.CreateDelete(OrderDetails.TBL);
del.Expreesion = OrderDetails._OrderID == 10350;
IDelete del1 = session.CreateDelete(Orders.TBL);
del1.Expreesion = Orders._OrderID == 10350;
session.Open();
session.BeginTran();//打开事务
try
{
del.Execute();
del1.Execute();
session.Commit();//提交事务
}
catch(Exception e_)
{
session.RollBack();//回滚事务
throw(e_);
}
}
6. 对象功能
组件还提供了对象映射机制的方式来访问数据库,通过操作映射对象把结果反映到数据库中或从数据库获取数据映射到相关的对象里。操作的对象发通过XML构造对象映射描述文档。
6.1. 获取对象
IDataSession.Load(System.Type type,object id)方法用于获取数据对象;type是映射对象的类型,id是对应数据表中的唯一键值。获取类型必须提供ID属性映射描述。加载过程中会自动加载关联对象。
应用事例:
using(IDataSession session = MappingContainer.ConfigContainer.OpenSession())
{
session.Open();
Employees emp = (Employees)session.Load(typeof(Employees),employeeid);
Console.Write(emp.FirstName + emp.LastName);
}
6.2. 修改对象
IDataSession.Update(object entity)方法用于更新对象;entity是需要更新的对象。更新对象类型必须提供ID属性映射描述。
应用事例:
using(IDataSession session = MappingContainer.ConfigContainer.OpenSession())
{
session.Open();
Employees emp = (Employees)session.Load(typeof(Employees),employeeid);
if(emp != null)
{
emp.FirstName = "fan";
emp.LastName ="henry";
session.Update(emp);
}
}
6.3. 添加对象
IDataSession.Save(object entity)方法用于添加对象;entity添加的对象。添加对象类型必须提供ID属性映射描述。
应用事例:
using(IDataSession session = MappingContainer.ConfigContainer.OpenSession())
{
Employees emp = new Employees();
emp.FirstName ="fan";
emp.LastName ="henry";
emp.BirthDate = DateTime.Parse("1979-1-28");
emp.HireDate = DateTime.Parse("2002-12-25");
emp.ReportsTo =1;
emp.Photo = new byte[0];
session.Open();
session.Save(emp);
Console.Write(emp.EmployeeID);
}
6.4. 删除对象
IDataSession.Delete(object entity)方法用于删除对象;entity删除的对象。删除对象类型必须提供ID属性映射描述。
应用事例:
using(IDataSession session = MappingContainer.ConfigContainer.OpenSession())
{
Employees emp = new Employees();
emp.EmployeeID = employeeid;
session.Open();
session.Delete(emp);
}
6.5. 获取对象集
IDataSession.List(System.Type type,IExpression expression)方法用于相关数据的对象集,对象集以IList接口的方式返回;type是获取对象的类型,expression是获取对象的条件表达式;方法默认不加载关联对象;如果需要加载关联对象可以通过些方法的其他重载版本获取。
应用事例:
private void LoadEmployees(HFSoft.Data.Expressions.Expression exp)
{
System.Collections.IList lst = null;
using(IDataSession session = MappingContainer.ConfigContainer.OpenSession())
{
session.Open();
lst = session.List(typeof(Employees),exp);
}
}
7. 条件表达式
组件提供了标准SQL条件表达式的支持。开发人员可能通过组件提供的对象可以直接在.NET下编写条件表式,在编写的过程除了保持传统SQL条件编写方式还提供.NET环境的编译检测;进一步保证了SQL语句在运行时的合法性。
参照表:
|
SQL比较关键字 |
组件相关对象 |
运算符 |
||
|
+ |
+ HFSoft.Data.Expressions.FieldAdapter派生类重载此运算符 |
- |
- HFSoft.Data.Expressions.FieldAdapter派生类重载此运算符 |
|
* |
* HFSoft.Data.Expressions.FieldAdapter派生类重载此运算符 |
|
/ |
/ HFSoft.Data.Expressions.FieldAdapter派生类重载此运算符 |
|
逻辑运 |
||
|
And |
& HFSoft.Data.Expressions. IExpression的实现者重载此运算符。 |
Or |
| HFSoft.Data.Expressions. IExpression的实现者重载此运算符。 |
|
聚合函数 |
||
|
Sum |
SqlMath.Sum |
Max |
SqlMath.Max |
|
Min |
SqlMath.Min |
|
Avg |
SqlMath.Avg |
|
Count |
SqlMath.Count |
|
比较运算符 |
||
|
= |
EqExpression类型, FieldAdapter派生类重载此运算符 |
<> |
NotEqExpression类型, FieldAdapter派生类重载此运算符 |
|
> |
RtExpression类型, FieldAdapter派生类重载此运算符 |
|
>= |
RtEqExpression类型,FieldAdapter派生类重载此运算符 |
|
< |
LeExpression类型, FieldAdapter派生类重载此运算符 |
|
<= |
LeEqExpression类型, FieldAdapter派生类重载此运算符 |
|
In |
InExpression类型, FieldAdapter派生类的In方法 |
|
NotIn |
InExpression类型, FieldAdapter派生类的NotIn方法 |
|
Like |
LikeExpression类型, FieldAdapter派生类的Like方法 |
|
Between |
BetweenExpression类型, FieldAdapter派生类的Between方法 |
|
Not Between |
BetweenExpression类型, FieldAdapter派生类的NotBetween方法 |
通过FieldAdapter派生类的特性可以创建很复杂的条件对象,编写方式基本和SQL保持一致。
应用事例:
SQL编写方式:
(OrderDate >= ‘1997-7-1’ and OrderDate <’1997-8-1’) and (EmployeeID ==5 or Employeeid =7)
组件编写方式:
(Orders._OrderDate >= DateTime.Parse("1997-7-1") & Orders._OrderDate < DateTime.Parse("1997-8-1") )&(Orders._EmployeeID ==5 | Orders._EmployeeID ==7)
8. 函数
8.1. 聚合函数
组件提供聚合函数(例如 SUM、AVG、COUNT、MAX 和 MIN)在查询结果集中生成汇总值。
可以调用HFSoft.Data.Expressions.SqlMath类型来获取相关聚合函,所有聚合函数以静态成员的方式调用。
应用事例:
1)统计指定雇员的订单数。
using(IDataSession session = MappingContainer.ConfigContainer.OpenSession())
{
IQuery query = session.CreateQuery(Orders.TBL);
query.Selects = new FieldAdapter[]{SqlMath.Count(Orders._ALL)};
query.Expreesion = Orders._EmployeeID == employeeid;
session.Open();
System.Data.DataSet myDS = query.ExecuteDataSet();
}
2)统计每张单订的总金额。
using(IDataSession session = MappingContainer.ConfigContainer.OpenSession())
{
IQuery query = session.CreateQuery(OrderDetails.TBL);
query.Selects = new FieldAdapter[]{OrderDetails._OrderID,
SqlMath.Sum(OrderDetails._UnitPrice*OrderDetails._Quantity*(1-OrderDetails._Discount)).As("Account")};
query.GroupBy = new FieldAdapter[]{OrderDetails._OrderID};
session.Open();
System.Data.DataSet myDS = query.ExecuteDataSet();
}
8.2. 数据库扩展函数
在扩展中…
9. 错误描述
9.1. 解释文件错误
n 1010,没有映射对象或映射描述信息
n 1020,分析类信息错误
n 1031,已存在ID描述信息