一个简单O/R M组件(HFSoft.Data).NET - 中国WEB开发者网络 (http://www.webasp.net) -- 技术教程 (http://www.webasp.net/article/) --- 一个简单O/R M组件(HFSoft.Data).NET (http://www.webasp.net/article/27/26597.htm) |
| -- 作者:未知 -- 发布日期: 2005-09-20 |
一直想用O/R M的模式去开应用系统;但在。NET下又没有成熟的产品,nhibernate虽然不错但结构比较复杂,如果出现问题维护起来也比较麻烦。所以打算自己编写这样一个组件,在使用、维护和扩展方面的都比较容易把握;对项目的后期维护也比较有利。组件功能上也远比不上nhibernate,只实现了单表和视图的映射操作、查询对象化等功能。在设计的过程也参考了nhibernate的设计方式,毕竟nhibernate的设计不错可以直接拿过来使用。根据自己的情况修改一下就可以了。
在设计时第一个考虑的问题就是组件对多类型数据库的支持,所以针对数据库提供者提取接口;在设计这个接口时nhibernate给我带来很大的启发;可以说是直接引用了它的设计原理。当数据库提供者接口完成后,就可以针对这个接口做数据库处理的工作了。
IDataSession
数据操作描述,包括找开连接、启用事务、插入对象、删除对象等操作。
IDriverType
数据库提供者描述,主要用于描述数据库类型关键的东西,如果数据库连接对象、对应的Command类型等。
IExpression 条件表达式描述,用于处理查询过程中的条件;从些接口实现的条件表达式有:=、>、<>、like、in等;
组件还有很多对象进行内部处理的:类的映射信息,主要和忝相就应的SQL语句和命令对象;缓存类用于缓存操作命令对象、命令对持久化接口等。
类和数据库的关系映射 实体类和数据库表的关联采用了XML文件描述,相应对nhibernate业说比较简单.
以下是描述employees类和employees表对映象关系。
类文件
using System; namespace NorthWind.Entitys { /// <summary> /// Employees /// </summary> public class Employees { public Employees() { // // TODO: 在此处添加构造函数逻辑 // } public const string F_EmployeeID="EmployeeID"; private Int32 mEmployeeID; /// <summary> /// [int identity] /// </summary> public Int32 EmployeeID { get { return mEmployeeID; } set { mEmployeeID = value; } } public const string F_LastName="LastName"; private String mLastName; /// <summary> /// [nvarchar] /// </summary> public String LastName { get { return mLastName; } set { mLastName = value; } } public const string F_FirstName="FirstName"; private String mFirstName; /// <summary> /// [nvarchar] /// </summary> public String FirstName { get { return mFirstName; } set { mFirstName = value; } } ……………….. ……………….. 映射关系的XML文件
<?xml version="1.0" encoding="utf-8" ?> <class name="NorthWind.Entitys.Employees,NorthWind.Entitys" table="Employees"> <id name="EmployeeID" column="EmployeeID" value="SELECT @@IDENTITY ,false"/> <property name="LastName" column="LastName"/> <property name="FirstName" column="FirstName"/> <property name="Title" column="Title"/> <property name="TitleOfCourtesy" column="TitleOfCourtesy"/> <property name="BirthDate" column="BirthDate"/> <property name="HireDate" column="HireDate"/> <property name="Address" column="Address"/> <property name="City" column="City"/> <property name="Region" column="Region"/> <property name="PostalCode" column="PostalCode"/> <property name="Country" column="Country"/> <property name="HomePhone" column="HomePhone"/> <property name="Extension" column="Extension"/> <property name="Photo" column="Photo"/> <property name="Notes" column="Notes"/> <property name="ReportsTo" column="ReportsTo"/> <property name="PhotoPath" column="PhotoPath"/> </class>
组件的使用 当类和映射文件建立以后,就通过组件对类的操作来实现数据操作。为了实现动态配置,组件配置的方式和nhibernate是一样的,只是配置节有所不同。
<configSections> <section name="dataconfig" type="HFSoft.Data.DataConfigSectionHandler, HFSoft.Data, Version=0.9.1.0, Culture=neutral, PublicKeyToken=null" /> </configSections> <dataconfig> <DriverType value="HFSoft.Data.SqlDriver, HFSoft.Data, Version=0.9.1.0, Culture=neutral, PublicKeyToken=null"/> <ConnectionString value="data source=.;initial catalog=northwind;user id=sa;pwd=;"/> <MappingAssemblys> <Assembly value="NorthWind.Entitys"/> </MappingAssemblys> <CacheCommands default="3"/> </dataconfig>
添加一条雇员信息 HFSoft.Data.MappingContainer mapContainer = HFSoft.Data.MappingContainer.ConfigContainer; using(HFSoft.Data.IDataSession session = mapContainer.OpenSession()) { session.Open(); NorthWind.Entitys.Employees emp = new NorthWind.Entitys.Employees(); emp.ReportsTo = 3; emp.FirstName ="fan"; emp.LastName = "henry"; emp.Photo = new byte[0]; emp.HireDate = DateTime.Parse(" emp.BirthDate = DateTime.Parse(" emp.City ="广州"; emp.Country ="中国"; session.Save(emp); MessageBox.Show(emp.EmployeeID.ToString());
}
获取所有雇员信息 using(HFSoft.Data.IDataSession session = mapContainer.OpenSession()) { session.Open(); System.Collections.IList myDS = session.List(typeof(NorthWind.Entitys.Employees),null); this.dataGrid1.DataSource = myDS; } 多条件查询(雇员编号大于等于3并且小于等于10或者姓包含fan) HFSoft.Data.Expression expression = new HFSoft.Data.Expression(); expression.Add(new HFSoft.Data.RtEqExpression(NorthWind.Entitys.Employees.F_EmployeeID,3)); expression.Add(new HFSoft.Data.LeEqExpression(NorthWind.Entitys.Employees.F_EmployeeID,10)); expression.Add(HFSoft.Data.UintType.Or,new HFSoft.Data.LikeExpression(NorthWind.Entitys.Employees.F_FirstName,"fan%")); using(HFSoft.Data.IDataSession session = mapContainer.OpenSession()) { session.Open(); System.Collections.IList myDS = session.List(typeof(NorthWind.Entitys.Employees),expression); this.dataGrid1.DataSource = myDS; } 获取雇员信息并修改 using(HFSoft.Data.IDataSession session = mapContainer.OpenSession()) { session.Open(); NorthWind.Entitys.Employees emp = (NorthWind.Entitys.Employees)session.Load(typeof(NorthWind.Entitys.Employees),41); emp.FirstName ="kfc"; session.Update(emp);
} 组件为了提高效率,增加了缓存机制。可以通过配置文件制定对插入数据、修改数据的命令对象进行缓存的数量。当组件需要调用对象的插入命令时就会从缓存中找,当找不到的情况下才创建相关命令对象,这样会减少创建所带来的性能问题;同样缓存会占用相应的内存资源。组件现在还决少查询命令对象、数据集、实体对象的缓存。实体对象缓存比较复杂,中间还存在着和数据库信息同步、频繁锁的问题;还没有想到较好的解决方法,暂时没有打算把实体缓存集成到组件中。 |
| webasp.net |