ORM框架-VB/C#.Net实体代码生成工具(EntitysCodeGenerate)【ECG】4.5
- 引言
- 内容
- ORM框架的实现VBCNet实体代码生成工具EntitysCodeGenerate
- 在开发中的实际应用
- 结束语
- 相关下载地址
摘要:VB/C#.Net实体代码生成工具(EntitysCodeGenerate)【ECG】是一款专门为.Net数据库程序开发量身定做的(ORM框架)代码生成工具,所生成的程序代码基于OO、ADO.NET、分层架构、ORM及反射+工厂设计模式等。支持.Net1.1及以上版本,可用于Oracle、SqlServer、Sybase、DB2、MySQL、Access、SQLite、PostgreSQL、DM(达梦)、PowerDesigner文件、Informix、Firebird、MaxDB、Excel等和OleDb、ODBC连接的数据库并可自定义,详见文档及安装文件的示例和工具的帮助文档。
关键字: VB/C#.Net实体代码生成工具 实体代码生成工具 EntitysCodeGenerate
预期读者: 软件开发及相关人员
难度等级: 中
当前版本: 4.5
目 录
1 引言
2 内容
2.1 ORM框架的实现:VB/C#.Net实体代码生成工具(EntitysCodeGenerate)
2.2 在开发中的实际应用
2.2.1 单个实体对象的数据库操作
1、获取一个实体对象信息
2、插入一个实体对象信息
3、更新一个实体对象信息
4、保存一个实体对象信息
5、删除一个实体对象信息
6、取得实体映射表数值字段的最大值+1
2.2.2 多个实体对象的数据库操作
1、实体集对象的使用
2、结合事务处理
2.2.3 数据查询(EQL)及通用DML操作
1、 常用实体对象查询
2、 ORM结构化查询
(1)、Select查询
(2)、From连接
(3)、Where语句的Condition条件
(4)、Order By排序功能
(5)、Group By分组条件及排序
(6)、结合事务处理的功能
(7)、自定义分页查询(Skip/Take)
3、Delete删除
4、Update更新
5、Insert插入
2.2.4 DbCore+SQL/存储过程
1、DbCore+SQL
2、DbCore+存储过程
3、DbCore执行SQL/存储过程的快捷用法
2.2.5 Extend辅助扩展功能
1、TableHelp辅助扩展
2、CommonHelp常用方法扩展
2.2.6 ORM的分析及与Xml、JSON、EString的交互
1、ORM的分析
2、与XML的交互
3、与JSON的交互
4、与String(即EString)的交互
2.2.7 LINQ的支持
1、Linq To Entitys
2.2.8 轻量级日志组件
1、简单日志配置
2、简单日志的使用
3 结束语
4 相关下载地址
1引言
2内容
2.1 ORM框架的实现:VB/C#.Net实体代码生成工具(EntitysCodeGenerate)
public classBaseEntity { public static string GetConnectionString() { return "User ID=scott;Password=tiger;Data Source=oracle9";//数据库连接可修改从别处读取 } public static DatabaseType GetDatabaseType() { return DatabaseType.Oracle; //数据库连接类型设置也可修改从别处读取 } …… } |
System.Database.DbCore结合实体类可将简单和复杂的数据库操作及事务处理更为方便的实现,下文着重介绍在实际中的应用。
2.2在开发中的实际应用
2.2.1 单个实体对象的数据库操作
这里以Oracle附带库DEPT为例来做说明,首先做对象的声明
DEPT entity =newDEPT(); |
此处以该对象来做阐述。
1、获取一个实体对象信息
实体的操作默认以主键为准,对单个实体信息的获取可简单如下实现:
entity.DEPTNO = 50; entity = entity.GetEntity(); |
返回主键字段DEPTNO=50的对象,若数据库中没有对应的记录则返回null。DEPT表的主键字段是DEPTNO,同时对联合主键也是支持的,下文同此;GetEntity同时提供其它指定条件的重载,也可以使用GetEntityByEntityCondition,当指定条件有多个记录符合时只返回首条记录;返回多条记录可使用GetDataTable方法。
在3.3版本之后也可通过多个构造函数来获取单个实体对象的信息等:
DEPT entity =newDEPT(50); //通过主键字段条件获取实体对象 DEPT entity =newDEPT("DEPTNO",50); //指定唯一字段条件获取实体对象 DEPT entity =newDEPT(newstring[] {"DEPTNO" },newobject[] { 50 }); |
2、插入一个实体对象信息
插入一个对象代码可如下所示:
entity.DEPTNO = 51; entity.DNAME = "DNAME1"; entity.LOC = "LOC1"; entity.Insert(); |
同时Insert提供多种相应的重载和InsertAll方法;区别是:Insert在插入记录时会比较对象初始的字段值,将与初始值不同的值插入,其余的以表字段的默认方式处理;InsertAll则是插入全部字段,即使是对象的初始值没有改变也会插入。
3、更新一个实体对象信息
更新一个对象代码可如下所示:
entity.DEPTNO = 51; entity.DNAME = "DNAME1"; entity.LOC = "LOC1"; entity.Update(); |
Update也提供多种相应的重载和UpdateAll方法;区别是:Update在更新记录时会比较对象初始的字段值,将与初始值不同的值进行更新,其余的表字段不更新;UpdateAll则是更新全部字段,即使是对象的初始值没有改变也会将对象的初始值更新到表里。
4、保存一个实体对象信息
保存是该工具新增的功能,即将插入和更新合并为一个保存方法,实体对象会自动根据主键约束解析是插入还是更新,代码如下所示:
entity.DEPTNO = 51; entity.DNAME = "DNAME1"; entity.LOC = "LOC1"; entity.Save(); |
这里是以主键为准,对多个联合主键也是支持的。保存是按主键判断的(没有主键的须指定约束字段),有就更新,没有就插入新记录。同时Save提供多种重载和SaveAll、SaveByEntityCondition方法,Save和SaveAll区别同插入和更新。
5、删除一个实体对象信息
删除可如下代码所示:
entity.DEPTNO = 51; entity.Delete(); |
删除操作默认以主键为准,支持联合主键,同时也提供多种指定条件的重载方法。最后附加说明,实体对象的增删改保存操作都会返回一个int值,该值返回表中记录受影响的行数。
从这些代码可以明显的看到,这里常用的增、删、改、查操作只需简单几句即可实现,少写了很多代码!
6、取得实体映射表数值字段的最大值+1
代码可如下:
int intID = entity.GetInt32MaxID(); |
这里获取实体对象对应表字段默认第一个主键的最大值ID+1,类型为整型,同时提供GetInt?MaxID多种重载,即有整型和长整型及指定字段等重载。
除此之外,还提供了一系列的CRUD扩展方法,如:InsertEx / UpdateEx / SaveEx / DelInsert / DelInsertEx 和 实体集对象的批量操作,如:entitys.ToDataTable / Save /SaveAll/SaveEx/Delete/DelInsert/DelInsertEx/GetMaxValue/GetMinValue/GetAvgValue/GetCount/GetSqlValue/GetSqlDataSet等;详见示例代码和生成的实体代码及相关帮助文档。其中实体集对象的批量操作自动启用事务处理,操作成功统一提交,失败时统一回滚。
本节介绍的都是单实体/表无事务的操作,下节介绍多实体/表及事务处理的操作。
2.2.2 多个实体对象的数据库操作
1、实体集对象的使用
实体集除了提供基本的Add和索引访问方法,同时也提供了相应与数据库操作的方法,如:Save/SaveAll/SaveEx/Delete/DelInsert/DelInsertEx/DelInsertAll/ToXml/ToXml_/FromXml/FromXmlFileToDataTable和实体集对象查询。实体集对象与数据库的操作释义同单个实体,并且会自动启动事务。实体集对象查询是通过实体集构造函数获取多实体对象信息,如:
DEPTS entity =newDEPTS(true); //获取所有部门信息 EMPS entitys = new EMPS ("DEPTNO",50) //获取DEPTNO=50所有雇员信息 EMPS entitys1 =newEMPS(newstring[] {"DEPTNO" },newobject[] { 50 }); DataTable dtbl = entitys.ToDataTable();//将获取的实体集对象信息转换到数据表DataTable |
2、结合事务处理
这里简略介绍实体对象结合System.Database.DbCore的事务处理是如何工作的,先看以下代码(可参见安装示例代码System.Database.Demo):
Entitys.Common.LC_WORKTYPE entity= new Entitys.Common.LC_WORKTYPE(); entity.ID = 1; entity.TYPENAME = "TYPENAME"; string strConnection = "Password=cc;User ID=cc;Data Source=oracle9"; DbCore dbCore = new DbCore(DatabaseType.Oracle, strConnection); dbCore.Open(); dbCore.BeginTransaction(); dbCore.Save(new Entitys.Common.LC_WORKTYPE(), entity); entity.DESCRIPTION = "类型描述"; dbCore.Save(new Entitys.Common.LC_WORKTYPE(), entity); entity.TYPENAME = "作业类型"; dbCore.Save(new Entitys.Common.LC_WORKTYPE(), entity); DataSet dst = dbCore.ExecuteDataSet("select * from lc_worktype"); entity.ID = 1; DataTable dt = dbCore.GetDataTableByEntityKey(entity); int intRecord = dbCore.Delete(entity); dt = dbCore.GetDataTableByEntityKey(entity); dbCore.CommitTransaction(); dbCore.Close(); |
这里使用另外一个实体LC_WORKTYPE(映射到XX系统的"作业类型"这张表),BeginTransaction()为开始事务的标志;CommitTransaction()为提交当前事务;还一个是RollbackTransaction()表示回滚当前事务,放弃当前所有数据的更改。这样在事务开始和提交或回滚之间可以进行多个实体的操作,并将结果最终一起提交或回滚撤销。这里Save有两个参数第一个是实体对象的初始类用于比较实体的初始值,第二个是要保存的对象,该方法依据主键自动判断是更新还是插入;与Save类似的方法有SaveAll,同时也有重载及SaveEx、Insert、InsertAll、InsertEx、Update、UpdaAll、Update Ex、Delete、IsExitByEntityKey、Exists、Get?MaxId等方法,可相互结合使用,方法都有详尽的说明及示例代码。执行中可单步跟踪,查看该事务下每步命令执行后对应的数据集信息。
下面再看以Oracle自带的scott库为例一段代码Delete、Insert、Update并结合事务使用的代码:
DbCore dbCore = null; try { EMP entity1 = new EMP(); DataSet dst = new DataSet(); entity1.EMPNO = 7369; //设置主键EMPNO为 entity1 = entity1.GetEntity(); //取得主键EMPNO为实体对象信息 //"User ID=scott;Password=tiger;Data Source=oracle9"; dbCore = new DbCore(Entitys.Common.BaseEntity.GetConnectionString()); dbCore.Open(); dbCore.BeginTransaction(); //选择当前事务下的所有雇员EMP的信息 dst = dbCore.SelectAll().From(entity1).ExecuteDataSet(); dbCore.Delete(entity1);//删除主键EMPNO为7369的记录 dst = dbCore.SelectAll().From(entity1).ExecuteDataSet();//查看当前事务下记录,当前删除记录将不在此显示 dbCore.Insert(newEMP(), entity1);//插入刚才删除主键EMPNO为7369的记录=dbCore.Save(new EMP(), entity1); dst = dbCore.SelectAll().From(entity1).ExecuteDataSet();//查看当前事务下记录,可见刚刚插入的新记录 entity1.SAL = entity1.SAL + 100;//薪水加100 dbCore.Update(newEMP(), entity1);//更新=dbCore.Save(new EMP(), entity1); dst = dbCore.SelectAll().From(entity1).ExecuteDataSet();//查看当前事务下记录,对应薪水SAL已更新 entity1.SAL = entity1.SAL - 100;//薪水减100 dbCore.Update(newEMP(), entity1);//更新=dbCore.Save(new EMP(), entity1); dst = dbCore.SelectAll().From(entity1).ExecuteDataSet();//查看当前事务下记录,对应薪水SAL已更新 dbCore.CommitTransaction(); dbCore.Close(); } catch (Exception ex) { if (dbCore != null) { if (dbCore.IsTransaction) dbCore.RollbackTransaction();//如果已经开始事务,则回滚事务 dbCore.Close(); } } |
上面的Insert、Update方法都可以Save方法来取代,Save方法会自动判断是Update还是Insert,这里只是用来展示之用。
(1)、Select查询
System.Database.DbCore类提供Select方法及其相应的重载,以SqlServer自带的pubs库为例,可见如下代码:
DataSet dst =newDataSet(); DbCore dbCore = new DbCore(DatabaseType.SqlServer, "Server=(local);User id=sa;Pwd=sa;Database=pubs"); |
DataSet dst = dbCore.SelectAll().From("sales").ExecuteDataSet(); |
DataSet dst = dbCore.SelectAll().From(SALESColumn.TableName).ExecuteDataSet(); |
DataSet dst = dbCore.Select(SALESColumn.ord_num).From(SALESColumn.TableName).ExecuteDataSet(); |
DataSet dst = dbCore.Select(SALESColumn.ord_num).SelectColumn(SALESColumn.ord_date).From(SALESColumn.TableName).ExecuteDataSet(); |
DataSet dst = dbCore.SelectAll().From(newSALES()).ExecuteDataSet(); |
其中的dbCore.SelectAll()方法缺省默认参数为查询所有字段,Select()不选择出任何字段,仅初始化实例,同时也可直接使用SQL语法的字符串或使用相应的ENTITYColumn类如SALESColumn的属性字段作为参数,或数组集合信息。也可用SelectColumn添加要查询的字段,SelectColumn(…)接受SQL表字段名字符串或ENTITYColumn类的属性字段格式的参数,SelectColumns(…)接受符合SelectColumn格式的数组参数,同时也提供SelectCustom(…)接受自定义的SQL语法的字符参数。同时鉴于SelectColumn等方法名较长,提供Add替代SelectColumn,AddMax、Min、Avg分别替代SelectColumnMax、Min、AvgValue各种同构方法,便于代码的抒写。
From(…)为查询的目标表名,这里使用的是SALESColumn.TableName,也可直接使用表名字符串,同时接受实体对象作为参数。ExecuteDataSet()执行查询并返回在内存当中的DataSet格式的结果数据集。ExecuteReader()执行查询并返回只读向前的数据结果集流IDataReader;ExecuteScalar()快速执行查询并返回第一行第一列的Object值,下同。
(2)、From连接
先见如下代码:
DataSet dst =newDataSet();DataSet dst1=newDataSet(); DbCore dbCore = new DbCore(DatabaseType.SqlServer, "Server=(local);User id=sa;Pwd=sa;Database=pubs"); |
dst = dbCore.SelectAll().From().JoinInner("sales", "stor_id ","stores","stor_id") .ExecuteDataSet(); |
dst = dbCore.SelectAll().From().JoinInner(SALESColumn.stor_id,STORESColumn.stor_id) .ExecuteDataSet(); |
dst = dbCore.SelectAll().From().JoinLeft("sales", "stor_id ","stores","stor_id") .ExecuteDataSet(); |
dst = dbCore.SelectAll().From().JoinLeft(SALESColumn.stor_id,STORESColumn.stor_id) .ExecuteDataSet(); |
dst = dbCore.SelectAll().From().JoinRight("sales", "stor_id ","stores","stor_id") .ExecuteDataSet(); |
dst = dbCore.SelectAll().From().JoinRight(SALESColumn.stor_id,STORESColumn.stor_id) .ExecuteDataSet() |
dst = dbCore.SelectAll().From().JoinFull("sales", "stor_id ","stores","stor_id") .ExecuteDataSet(); |
dst = dbCore.SelectAll().From().JoinFull(SALESColumn.stor_id,STORESColumn.stor_id) .ExecuteDataSet(); |
这里是以SqlServer系统自带pubs示例库的表sales、stores为例介绍的,JoinInner为内连接、JoinLeft为左外连接、JoinRight为右外连接、JoinFull完全外连接。参数可直接使用表名及表字段名字符串,或使用SALESColumn、 STORESColumn类,其中使用实体类静态属性字段代码可读性及维护性更好些。下面看下Where的使用。
(3)、Where语句的Condition条件
DataSet dst =newDataSet(); DataSet dst1 = newDataSet(); DbCore dbCore = new DbCore(DatabaseType.SqlServer, "Server=(local);User id=sa;Pwd=sa;Database=pubs"); |
dst = dbCore.SelectAll().From().JoinInner("sales", "stor_id ","stores","stor_id") .Where().ConditionAndEqual("sales","stor_id", 7067).ExecuteDataSet(); |
dst1 = dbCore.SelectAll().From().JoinInner(SALESColumn.stor_id,STORESColumn.stor_id) .Where().ConditionAndEqual(SALESColumn.stor_id, 7067).ExecuteDataSet(); |
dst = dbCore.SelectAll().From().JoinInner("sales", "stor_id ","stores","stor_id") .Where().ConditionAndGreat("sales","stor_id", 7896) . ConditionOrLessEqual("sales","stor_id", 7067).ExecuteDataSet(); |
dst1 = dbCore.SelectAll().From().JoinInner(SALESColumn.stor_id,STORESColumn.stor_id) .Where().ConditionAndGreat(SALESColumn.stor_id, 7896) .ConditionOrLessEqual(SALESColumn.stor_id, 7067).ExecuteDataSet(); |
dst = dbCore.SelectAll().From("sales").FromTable("stores") .Where().ConditionColumnAndEqual("sales", "stor_id","stores","stor_id"). ConditionAndBetweenAnd("sales", "stor_id", 7067, 7896).ExecuteDataSet(); |
dst1 = dbCore.SelectAll().From(SALESColumn.TableName).FromTable(STORESColumn.TableName) .Where().ConditionColumnAndEqual(SALESColumn.stor_id, STORESColumn.stor_id). ConditionAndBetweenAnd(SALESColumn.stor_id, 7067, 7896).ExecuteDataSet(); |
这里再次展示了使用字符串和ENTITYColumn类的相互比较,可见使用ENTITYColumn更直观,可读及维护性更好些。Where()是不带参数的实例化方法,所添加的查询条件均以Condition…开头,在这里可以添加关系运算包括Equal(=), Less(<),Great(>), LessEqual(<=), GreatEqual (>=), NotEqual(<>、!=), BetweenAnd, in, not in, null, not null,like,not like和各自的关系and,or比较 及表字段与字段之间的=,<, >, <= ,>=,<>关系and,or的连接等;另外还可以添加自定义的Where条件语句等。
(4)、Order By排序功能
这里切换到Oracle数据库,以Oracle自带的scott用户为例,先看如下代码:
DataSet dst =newDataSet(); EMP entity = newEMP(); DbCore dbCore = newDbCore(DatabaseType.Oracle, "Password=tiger;User ID=scott;Data Source=oracle9"); |
dst = dbCore.SelectAll().From(entity) .Where().ConditionAndGreat(entity, EMPColumn.DEPTNO, 20) .OrderBy(EMPColumn.SAL).ExecuteDataSet(); |
dst = dbCore.SelectAll().From(entity) .Where().ConditionAndGreat(entity, EMPColumn.DEPTNO, 20) .OrderBy().Asc(EMPColumn.SAL).ExecuteDataSet(); |
dst = dbCore.SelectAll().From(entity) .Where().ConditionAndGreat(entity, EMPColumn.DEPTNO, 20) .OrderBy().Desc(EMPColumn.SAL).ExecuteDataSet(); |
dst = dbCore.SelectAll().From(EMPColumn.TableName) .Where().ConditionAndGreat(EMPColumn.DEPTNO, 20).ExecuteDataSet(); |
其中entity为雇员表EMP对应的实体对象,这里使用查询表名的地方也可直接用实体对象。OrderBy默认不带排序参数,只实例化对象,也可带排序字段,排序方式为升序;其后使用Asc添加升序字段,Desc添加降序字段。
(5)、GroupBy分组条件及排序
这里同样以Oracle自带的scott用户为例,先看如下代码:
DataSet dst =newDataSet(); DataSet dst1 = newDataSet(); EMP entity = newEMP(); DbCore dbCore = newDbCore(DatabaseType.Oracle, "Password=tiger;User ID=scott;Data Source=orac"); |
dst = dbCore.Select().SelectColumnMaxValue(EMPColumn.EMPNO) .SelectColumnMinValue(EMPColumn.EMPNO).SelectColumnAvgValue(EMPColumn.EMPNO) .From(EMPColumn.TableName) .GroupBy(EMPColumn.DEPTNO).Column(EMPColumn.SAL) .Having().ConditionAndGreatEqual(EMPColumn.DEPTNO,10) .ConditionAndLessEqual(EMPColumn.DEPTNO, 40).ExecuteDataSet(); |
dst1 = dbCore.Select().AddMax(EMPColumn.EMPNO) .AddMin(EMPColumn.EMPNO).AddAvg(EMPColumn.EMPNO) .From(EMPColumn.TableName) .GroupBy(EMPColumn.DEPTNO).Column(EMPColumn.SAL) .Having().ConditionAndGreatEqual(EMPColumn.DEPTNO, 10) .ConditionAndLessEqual(EMPColumn.DEPTNO, 40).ExecuteDataSet(); |
dst = dbCore.Select().SelectColumn(EMPColumn.DEPTNO).SelectColumn(EMPColumn.SAL) .SelectColumnMaxValue(EMPColumn.EMPNO).SelectColumnMinValue(EMPColumn.EMPNO) .SelectColumnAvgValue(EMPColumn.EMPNO) .From(EMPColumn.TableName) .GroupBy(EMPColumn.DEPTNO).Column(EMPColumn.SAL) .Having().ConditionAndGreatEqual(EMPColumn.DEPTNO, 10) .ConditionAndLessEqual(EMPColumn.DEPTNO, 40) .OrderBy(EMPColumn.DEPTNO).Asc(EMPColumn.SAL).Asc("3").ExecuteDataSet(); |
dst1 = dbCore.Select().Add(EMPColumn.DEPTNO).Add(EMPColumn.SAL) .AddMax(EMPColumn.EMPNO).AddMin(EMPColumn.EMPNO).AddAvg(EMPColumn.EMPNO) .From(EMPColumn.TableName) .GroupBy(EMPColumn.DEPTNO).Column(EMPColumn.SAL) .Having().ConditionAndGreatEqual(EMPColumn.DEPTNO, 10) .ConditionAndLessEqual(EMPColumn.DEPTNO, 40) .OrderBy(EMPColumn.DEPTNO).Asc(EMPColumn.SAL).Asc("3").ExecuteDataSet(); |
dst = dbCore.Select().SelectColumn(EMPColumn.DEPTNO).SelectColumn(EMPColumn.SAL) .SelectColumnMaxValue(EMPColumn.EMPNO).SelectColumnMinValue(EMPColumn.EMPNO) .SelectColumnAvgValue(EMPColumn.EMPNO) .From(EMPColumn.TableName) .Where().ConditionAndBetweenAnd(EMPColumn.MGR, 7698, 7788) .ConditionAndGreatEqual(EMPColumn.HIREDATE, newDateTime(1981, 5, 1)) .ConditionAndLessEqual(EMPColumn.HIREDATE,DateTime.Today) .GroupBy(EMPColumn.DEPTNO).Column(EMPColumn.SAL) .Having().ConditionAndGreatEqual(EMPColumn.DEPTNO, 10) .OrderBy(EMPColumn.DEPTNO).Asc(EMPColumn.SAL).Asc("3").ExecuteDataSet(); |
dst1 = dbCore.Select().Add(EMPColumn.DEPTNO).Add(EMPColumn.SAL) .AddMax(EMPColumn.EMPNO).AddMin(EMPColumn.EMPNO).AddAvg(EMPColumn.EMPNO) .From(EMPColumn.TableName) .Where().ConditionAndBetweenAnd(EMPColumn.MGR, 7698, 7788) .ConditionAndGreatEqual(EMPColumn.HIREDATE, newDateTime(1981, 5, 1)) .ConditionAndLessEqual(EMPColumn.HIREDATE,DateTime.Today) .GroupBy(EMPColumn.DEPTNO).Column(EMPColumn.SAL) .Having().ConditionAndGreatEqual(EMPColumn.DEPTNO, 10) .OrderBy(EMPColumn.DEPTNO).Asc(EMPColumn.SAL).Asc("3").ExecuteDataSet(); |
dst = dbCore.Select().SelectColumn(EMPColumn.DEPTNO).SelectColumn(EMPColumn.SAL) .SelectColumnMaxValue(EMPColumn.EMPNO).SelectColumnMinValue(EMPColumn.EMPNO) .SelectColumnAvgValue(EMPColumn.EMPNO) .From(EMPColumn.TableName) .Where().ConditionAndGreatEqual(EMPColumn.EMPNO, 7654) .GroupBy(EMPColumn.DEPTNO).Column(EMPColumn.SAL).ExecuteDataSet(); |
dst = dbCore.Select().SelectColumn(EMPColumn.DEPTNO).SelectColumn(EMPColumn.SAL) .SelectColumnMaxValue(EMPColumn.EMPNO).SelectColumnMinValue(EMPColumn.EMPNO) .SelectColumnAvgValue(EMPColumn.EMPNO) .From(EMPColumn.TableName) .Where().ConditionAndGreatEqual(EMPColumn.EMPNO, 7654) .GroupBy(EMPColumn.DEPTNO).Column(EMPColumn.SAL) .ConditionAndLessEqual(EMPColumn.DEPTNO, 40) .OrderBy(EMPColumn.DEPTNO).Asc(EMPColumn.SAL).Asc("3").ExecuteDataSet(); |
dst = dbCore.Select().SelectColumn(EMPColumn.DEPTNO).SelectColumn(EMPColumn.SAL) .SelectColumnMaxValue(EMPColumn.EMPNO).SelectColumnMinValue(EMPColumn.EMPNO) .SelectColumnAvgValue(EMPColumn.EMPNO) .From(EMPColumn.TableName) .Where().ConditionAndBetweenAnd(EMPColumn.MGR, 7698, 7788) .GroupBy(EMPColumn.DEPTNO).Column(EMPColumn.SAL) .Having().ConditionAndGreatEqual(EMPColumn.DEPTNO, 10) .ConditionAndLessEqual(EMPColumn.DEPTNO, 40) .OrderBy(EMPColumn.DEPTNO).Asc(EMPColumn.SAL).Asc("3").ExecuteDataSet(); |
这里dst、dst1变量分别对应同样功能不同语句写法的数据集信息。同时展示了Add替代SelectColumn;AddMax、Min、Avg分别替代SelectColumnMax、Min、AvgValue的示例代码。Where和GroupBy、Having、OrderBy可同时使用,也可分开使用。最后三个展示了分别以Where和GroupBy、Having、OrderBy分开使用的例子。其中分组使用Column(…)添加分组字段。可以很明显的看出些语句的功能,和SQL语句的抒写几乎一致。如:倒数第四、五段的代码(粗体部分,两段代码功能相同,只是使用方法略异)换算成SQL语句就是(假设今天是2009-10-11):
SELECT emp.deptno, emp.sal, MAX(emp.empno) AS max_emp_empno, MIN(emp.empno) AS min_emp_empno, AVG(emp.empno) AS avg_emp_empno FROM emp WHERE emp.mgr BETWEEN 7698 AND 7788 AND emp.hiredate >= to_date('1981-5-1', 'yyyy-mm-dd') AND emp.hiredate <= to_date('2009-10-11', 'yyyy-mm-dd') GROUP BY emp.deptno, emp.sal HAVING emp.deptno >= 10 ORDER BY deptno ASC, sal ASC, 3 ASC |
和直接编写SQL很相似,省去许多代码量,且可读性高,维护也方便。
(6)、结合事务处理的功能
(1)-(5)介绍的没有加入事务处理功能,下面介绍结合事务的使用,先看如下代码:
DataSet dst = new DataSet(); DbCore dbCore = new DbCore(DatabaseType.Oracle, "Password=tiger;User ID=scott;Data Source=orac"); try { dbCore.Open();//--打开数据库连接 dbCore.BeginTransaction();//开始事务 int intRecordCount = dbCore.DeleteFrom(EMPColumn.TableName).ExecuteNonQuery(); dst = dbCore.SelectAll().From(EMPColumn.TableName).ExecuteDataSet(); dbCore.RollbackTransaction();//回滚撤销事务 dst1 = dbCore.SelectAll().From(newEMP()).ExecuteDataSet(); dbCore.Close();//--关闭数据库连接 } catch (Exception ex) { if (dbCore != null) dbCore.Close(); MessageBox.Show(ex.Message); } |
这里仍然是以Oracle自带的scott用户为例,其中的Data Source可以选择任何Oracle的服务名。这里有必要说明的是使用了打开、关闭数据库连接,因为要使用事务所以需要先打开数据库连接,前文介绍没有使用事务的,该步骤略过了。该例的功能是先删除EMP表的所有数据再查询该表的所以信息,可看到在当前事务下是没有信息的,然后在回滚事务,再查询就又有数据了,这正是事务所起的作用。同时需要注意的是,数据库连接打开后要关闭,且当中间出现异常时也应关闭已打开的数据库连接,以释放资源。
DataSet dstSqlite = dbCore.Select().Add(Entity.Common.SQLite.t_demo.s_z) .Add(Entity.Common.SQLite.t_demo.s_a).Add("b") .From(Entity.Common.SQLite.t_demo.s_TableName) .OrderBy().Asc("z").Skip(1).Take(2).ExecuteDataSet(); int countSqlite = dstSqlite.Tables[0].Rows.Count; |
仍然以Oracle自带的scott用户为例,并结合事务处理,先看如下代码:
try { DataSet dst =newDataSet(); dst = dbCore.SelectAll().From(newEMP()).ExecuteDataSet(); dbCore.Open();//--打开数据库连接 dbCore.BeginTransaction();//开始使用事务 EMP entity = new EMP(); entity.EMPNO = 7782; intRecordCount = dbCore.Delete(entity); dst = dbCore.SelectAll().From(EMPColumn.TableName).ExecuteDataSet(); intRecordCount = dbCore.DeleteFrom(EMPColumn.TableName) .Where().ConditionAndEqual(EMPColumn.DEPTNO, 10).ExecuteNonQuery(); dst = dbCore.SelectAll().From(EMPColumn.TableName).ExecuteDataSet(); intRecordCount = dbCore.DeleteFrom(new EMP()).ExecuteNonQuery(); dst = dbCore.SelectAll().From(EMPColumn.TableName).ExecuteDataSet(); dbCore.RollbackTransaction();//回滚结束事务 dst = dbCore.SelectAll().From(EMPColumn.TableName).ExecuteDataSet(); dbCore.Close();//--关闭数据库连接 } catch (Exception ex) { if (dbCore != null) dbCore.Close(); } |
仍然以Oracle自带的scott用户为例,并结合事务处理,先看如下代码:
DbCore dbCore = null; try { dbCore = PublicClass.GetNewDbCore(); dbCore.Open(); dbCore.BeginTransaction(); EMP entity = new EMP(); entity.EMPNO = 7499; entity = entity.GetEntity(dbCore); dbCore.Update(EMPColumn.TableName).Set(EMPColumn.SAL, entity.SAL + 100) .Set(EMPColumn.COMM, entity.COMM+ 100) .Set(EMPColumn.HIREDATE,DateTime.Today) .Where().ConditionAndEqual(EMPColumn.EMPNO, 7499).ExecuteNonQuery(); DataSet dst = dbCore.SelectAll().From(EMPColumn.TableName) .Where().ConditionAndEqual(EMPColumn.EMPNO, 7499).ExecuteDataSet();//查询 dbCore.Update(EMPColumn.TableName).Set(EMPColumn.SAL, entity.SAL) .Set(EMPColumn.COMM, entity.COMM) .Set(EMPColumn.HIREDATE, entity.HIREDATE) .Where().ConditionAndEqual(EMPColumn.EMPNO, 7499).ExecuteNonQuery();//恢复原值 dst = dbCore.SelectAll().From(EMPColumn.TableName) .Where().ConditionAndEqual(EMPColumn.EMPNO, 7499).ExecuteDataSet();//查询 dbCore.CommitTransaction();//提交事务 dbCore.Close(); } catch (Exception ex) { if (dbCore != null) { if (dbCore.IsTransaction) dbCore.RollbackTransaction();//如果已经开始事务,则回滚事务 dbCore.Close(); } throw ex; } |
5、Insert插入
用法同上,不再详细赘述,这里换张表以作区别,可见示例代码,如下所示:
DbCore dbCore = null; try { dbCore = GetDbCore; dbCore.Open(); int count = dbCore.InsertInto(T_DEMO.s_TableName).Values(T_DEMO.s_C_ID,GetKeyId) .Values(T_DEMO.s_C_NAME,"NameInsert").Values(T_DEMO.s_C_IDCARD,"340221196606066066") .Values(T_DEMO.s_C_DATE,DateTime.Today).Values(T_DEMO.s_C_INT,10) .Values(T_DEMO.s_C_FLOAT,11.11).Values(T_DEMO.s_C_EIDTDATE, DateTime.Now) .ExecuteNonQuery(); dbCore.Close(); return count; } catch (Exception ex) { if (dbCore != null) dbCore.Close(); throw ex; } |
2.2.4 DbCore+SQL/存储过程
诚然ORM并不是万能的,当遇到特别复杂的数据处理、海量数据运算、性能瓶颈优化或弥补设计的不足时(尽管不是很多,但也很重要),还应归结到SQL语句或存储过程来实现才是好的选择。实际项目中仍然会有海量复杂的数据处理或复杂子查询、SQL语句优化和存储过程等,DbCore提供了良好的解决方案,很好的解决了项目中10%-20%的那部分功能。该组件支持目前市场上ADO.NET支持的各种类型的数据库,可执行自定义编写的SQL语句和存储过程等,可针对复杂功能的特殊处理并对项目瓶颈问题作性能优化等操作。
System.Database.DbCore可直接用于Oracle、SqlServer、Sybase、DB2、MySql、SQLite、PostgreSQL、Access、DM(达梦)、Informix、Firebird、MaxDB和支持OleDb、Odbc连接类型的数据库,实例代码分别如下:
DbCore dbCore =newDbCore(DatabaseType.Oracle, “OracleConnectionString”); |
DbCore dbCore =newDbCore(DatabaseType.ODPNet, “OracleConnectionString”);//ODP.NET方式 |
DbCore dbCore =newDbCore(DatabaseType.SqlServer, “SqlServerConnectionString”); |
DbCore dbCore =newDbCore(DatabaseType.Sybase, “SybaseConnectionString”); |
DbCore dbCore =newDbCore(DatabaseType.DB2, “DB2ConnectionString”); |
DbCore dbCore =newDbCore(DatabaseType.MySql, “MySqlConnectionString”); |
DbCore dbCore =newDbCore(DatabaseType.SQLite, “SQLiteConnectionString”); |
DbCore dbCore =newDbCore(DatabaseType.PostgreSQL, “PostgreSQLConnectionString”); |
DbCore dbCore =newDbCore(DatabaseType.Access, “AccessConnectionString”); |
DbCore dbCore =newDbCore(DatabaseType.Dm, “DmConnectionString”); |
DbCore dbCore =newDbCore(DatabaseType.Informix, “InformixConnectionString”); |
DbCore dbCore =newDbCore(DatabaseType.Firebird, “FirebirdConnectionString”); |
DbCore dbCore =newDbCore(DatabaseType.MaxDB, “MaxDBConnectionString”); |
DbCore dbCore =newDbCore(DatabaseType.OleDb, “OleDbConnectionString”); |
DbCore dbCore =newDbCore(DatabaseType.Odbc, “OdbcConnectionString”); |
1、DbCore+SQL
下面看一段适合Oracle和SqlServer访问的通用SQL代码:
DbCore dbCore = PublicClass.GetNewDbCore(); string strParaToken = dbCore.GetCurrentParameterToken; //对应数据库的参数前导符 string strSql = "INSERT INTO dept (deptno, dname, loc) VALUES ("+ strParaToken+"deptno, "+ strParaToken+ "dname, " + strParaToken+ "loc)"; dbCore.Open(); //打开数据库连接 dbCore.BeginTransaction(); //开始事务 DBCommandWrapper cmd = dbCore.GetSqlStringCommandWrapper(strSql); //cmd.AddParameter(..);//为命令增加一个参数实例 cmd.AddInParameter(strParaToken + "deptno", DbType.Int32, 99); cmd.AddInParameter(strParaToken + "dname", DbType.String, "部门名称"); cmd.AddInParameter(strParaToken + "loc", DbType.AnsiString, "locTest"); int intMaxDeptId = dbCore.GetInt32MaxId("dept","deptno");//当前表的deptno最大值 dbCore.ExecuteNonQuery(cmd); intMaxDeptId = dbCore.GetInt32MaxId("dept","deptno");//插入数据deptno=99之后当前表的deptno最大值 strSql = "DELETE dept WHERE deptno = " + strParaToken+"deptno"; DBCommandWrapper cmd1 = dbCore.GetSqlStringCommandWrapper(strSql); cmd1.AddInParameter(strParaToken + "deptno", DbType.Int32, 99); dbCore.ExecuteNonQuery(cmd1); intMaxDeptId = dbCore.GetInt32MaxId("dept","deptno");//删除数据deptno=99之后当前表的deptno最大值 dbCore.RollbackTransaction();//回滚撤销事务。等于该方法什么都没做,只是演示作用 intMaxDeptId = dbCore.GetInt32MaxId("dept","deptno"); dbCore.Close();//关闭数据库连接 |
其中第一句的PublicClass.GetNewDbCore()方法体代码可以是newDbCore(DatabaseType.Oracle, “OracleConnectionString”)也可以是newDbCore(DatabaseType.SqlServer, “SqlServerConnectionString”),当new的是Oracle时即表示操作访问的是Oracle数据库,当new的是SqlServer即表示操作访问的是SqlServer数据库。dbCore.GetCurrentParameterToken即是获取对应数据库连接参数的前导符(如:Oracle是“:”,SQLServer是“@”等),这里也可以结合使用dbCore.StandardSqlWithParameters方法对当前带参数的SQL语句进行标准化通用处理,即所写SQL可以用于如MySql/Access数据库等。这里的数据库操作同样也是可以同实体对象一块协同工作。dbCore.GetSqlStringCommandWrapper(…)创建一个SQL语句的命令,dbCore.GetStoredProcCommandWrapper(…)创建一个执行存储过程的命令,可根据项目自身实际需要选择使用。
对专有数据库命令也可以转化为指定数据库命令来使用,这样可针对该数据库特性使用更多的方法,如Oracle、SqlServer的命令转化可像下列代码来转化:
OracleCommandWrapper cmd = dbCore.GetSqlStringCommandWrapper(strSql) asOracleCommandWrapper; |
SqlCommandWrapper cmd = dbCore.GetSqlStringCommandWrapper(strSql) asSqlCommandWrapper; |
…… |
不带参数SQL语句的快捷用法
这里顺便说明一下,当程序执行出现异常时可使用dbCore.Close()来关闭当前打开的数据库连接(当然如果不显式关闭连接,DbCore在实例销毁时检测到该实例未关闭连接也会自动关闭,但这样无疑一直占据着资源,不推荐,建议及时关闭及时释放资源),如下代码所示:
catch (Exception ex) { if (dbCore != null) { if (dbCore.IsTransaction) { dbCore.RollbackTransaction();//如果已经开始事务,则回滚事务 } dbCore.Close(); } throw ex; } |
最后再说一个System.Database.DbCoreConnectLimit.AllDBMaxConnectionCount,可以设置数据库打开的最大连接数目,默认不受限制。
2、DbCore+存储过程
DbCore+存储过程标准用法:
DBCommandWrapper cmd = dbCore.GetStoredProcCommandWrapper("[包名.]存储过程名"); //cmd.AddInParameter(... dbCore.ExecuteNonQuery(cmd); |
OracleCommandWrapper cmd = dbCore.GetStoredProcCommandWrapper("[包名.]存储过程名")asOracleCommandWrapper; //cmd.AddInParameter(... //cmd.AddOutParameter(... //cmd.AddParameter(... //cmd.AddCursorOutParameter(... dbCore.ExecuteDataSet(cmd); |
同时DbCore也提供了对存储过程的一个快捷用法:
dbCore.ExecuteStoredProcedure("[包名.]存储过程名"); |
下面就以Oracle为例,看下DbCore+存储过程的具体写法:
DbCore dbCore = null; try { string strConnection = "Password=cc;User ID=cc;Data Source=oracle9"; DbCore dbCore = new DbCore(DatabaseType.Oracle, strConnection); dbCore.Open(); dbCore.BeginTransaction(); int count; OracleCommandWrapper cmd = dbCore.GetStoredProcCommandWrapper("storedProcedure.NameA")asOracleCommandWrapper; //cmd.AddInParameter( //cmd.AddOutParameter( //cmd.AddParameter( //cmd.AddCursorOutParameter( count = dbCore.ExecuteNonQuery(cmd); cmd = dbCore.GetStoredProcCommandWrapper("storedProcedure.NameB")asOracleCommandWrapper; //cmd.AddInParameter( count += dbCore.ExecuteNonQuery(cmd); //count += dbCore.ExecuteStoredProcedure("storedProcedure.NameC"); dbCore.CommitTransaction(); dbCore.Close(); return count; } catch (Exception ex) { if (dbCore != null) { if (dbCore.IsTransaction) dbCore.RollbackTransaction(); dbCore.Close(); } throw ex; } |
3、DbCore执行SQL/存储过程的快捷用法
如下所示:
DbCore dbCore = new DbCore(myOracle.BaseEntity.GetConnectionString()); DataSet dst = dbCore.CreateSQL("select * from emp where deptno = :deptno") .AddInParameter("deptno",DbType.Int32, 20).ExecuteDataSet(); |
DbCore dbCore = new DbCore(myOracle.BaseEntity.GetConnectionString()); int intCount = dbCore.CreateStoredProcedure("[包名.]存储过程名") .AddInParameter("deptno",DbType.Int32, 20).ExecuteNonQuery(); |
许多工具都提供例外辅助的功能,该工具也不例外,简要介绍如下:
DbCore dbCore = PublicClass.GetNewDbCore(); DataTable dt1 = dbCore.SelectAll().From(EMPColumn.TableName).ExecuteDataSet().Tables[0]; DataTable dt2 = dbCore.SelectAll().From(DEPTColumn.TableName).ExecuteDataSet().Tables[0]; DataTable dt3 = TableHelp.MergeTable(dt1, dt2,"DEPTNO");//按部门编号DEPTNO列将表dt2的数据合并到dt1 DataTable dt3_ = TableHelp.MergeTable(dt2, dt1,"DEPTNO");//按部门编号DEPTNO列将表dt1的数据合并到dt2,dt1中有多行数据对应,取首行的数据,没有对应的数据为空 DataTable dt4 = TableHelp.AddTableRowNumCol(dt3); //给dt3添加行号 DataTable dt5 = TableHelp.GetTableTopRows(dt4, 5); //获取前5行 DataTable dt6 = TableHelp.GetTableSubRows(dt4, 6, 10); //获取dt4从第6行到第10行 DataTable dt7 = TableHelp.GetTableSubRows(dt4, 11, 20);//获取dt4从第11行到第20行,注:无20行取到最后一行 DataTable dt8 = TableHelp.GetTableBottomRows(dt4, 5); //获取dt4后5行 dt8 = TableHelp.GetTableBottomRows(dt4, 50); //获取dt4后50行;dt4没有后50行,从后面往前取到最前面存在行 DataTable dt9 = TableHelp.JoinInner(dt1, dt2,"DEPTNO"); //内连接 DataTable dt10 = TableHelp.JoinInner(dt1, dt2,"deptno"); //内连接 DataTable dt11 = TableHelp.JoinLeft(dt1, dt2,"DEPTNO"); //左外连接 DataTable dt12 = TableHelp.JoinRight(dt1, dt2,"DEPTNO"); //右外连接 DataTable dt13 = TableHelp.JoinLeft(dt2, dt1,"DEPTNO"); //左外连接 DataTable dt14 = TableHelp.JoinFull(dt1, dt2,"DEPTNO"); //完全外连接 DataTable dt15 = TableHelp.SortTable(dt1,"deptno", SortDirection.Asc); DataTable dt16 = TableHelp.SortTable(dt1,"deptno"); DataTable dt17 = TableHelp.SortTable(dt1,"deptno", SortDirection.Asc,"sal",SortDirection.Asc); DataTable dt18 = TableHelp.SortTable(dt1,"deptno","sal"); DataTable dt19 = TableHelp.SortTable(dt1,"deptno", SortDirection.Desc, "sal",SortDirection.Desc); DataTable dt20 = TableHelp.SortTableDesc(dt1,"deptno", "sal"); DataTable dt21 = TableHelp.SortTable(dt1,"deptno", SortDirection.Asc, "sal",SortDirection.Desc); TableHelp.DataTableToExcel(dt1,@"C:\Documents and Settings\楚涛\桌面\temp1.xls"); DataSet dst = new DataSet(); DataTable dt22 = dt1.Copy(); //修改表名,DataTable默认TableName="Table",DataSet集合的DataTable.TableName不能同名 dt22.TableName = "EMP"; DataTable dt23 = dt2.Copy(); //修改表名,DataTable默认TableName="Table",DataSet集合的DataTable.TableName不能同名 dt23.TableName = "DEPT"; dst.Tables.Add(dt22); dst.Tables.Add(dt23); TableHelp.DataSetToExcel(dst,@"C:\Documents and Settings\楚涛\桌面\temp2.xls"); |
同时也提供通过过滤条件选择DataTable行、合并数据表行信息、转换数据表列值对并以DataTable的形式返回的常用方法,如下所示:
DataTable dt24 = TableHelp.GetTableSelect(dt1,"deptno=10");//选取deptno=10的所有信息,并以DataTable的形式返回 DataTable dt25 = TableHelp.GetTableSelect(dt1,"deptno=20");//选取deptno=20的所有信息,并以DataTable的形式返回 DataTable dt26 = TableHelp.TableAppend(dt24, dt25);//将dt23数据按行附加到dt22,并以新的结果数据表的形式返回 string[,] strArray = new string[1, 2]; strArray[0, 0] = "SCOTT"; strArray[0, 1] = "scott/tiger"; DataTable dt27 =TableHelp.ReplacleTableColValue(dt26,"ename", strArray); |
string str1 = CommonHelp.NumberToRMB(1); //"壹元整" str1 = CommonHelp.NumberToRMB(102); //"壹佰零贰元整" str1 = CommonHelp.NumberToRMB(1000234); //"壹佰万零贰佰叁拾肆元整" str1 = CommonHelp.NumberToRMB(1000023456); //"壹拾亿零贰万叁仟肆佰伍拾陆元整" str1 = CommonHelp.NumberToRMB(100000234567); //"壹仟亿零贰拾叁万肆仟伍佰陆拾柒元整" decimal dec = 1234007890123.45M; str1 = CommonHelp.NumberToRMB(dec); //"壹万贰仟叁佰肆拾亿零柒佰捌拾玖万零壹佰贰拾叁元肆角伍分" string str = string.Empty; for (int i= 0; i< 1000; i++) { str += CommonHelp.GetOnlyID() + "\r\n";//唯一随机数字固定长度为20的数字字符串 } MessageBox.Show(str); str = CommonHelp.GetID20();//唯一随机数字固定长度为的数字字符串 str = CommonHelp.GetID25();//唯一随机数字固定长度为的数字字符串 str = CommonHelp.GetID30();//唯一随机数字固定长度为的数字字符串 string str1 = "abcdEFGH"; bool isHasChinese = CommonHelp.IsHasChineseWord(str1); //false不含有中文字符 str1 = "abcd啊EFGH"; isHasChinese = CommonHelp.IsHasChineseWord(str1); //true含有中文字符 |
还有其他常用方法和加密/解密常用方法扩展类CryptographyHelp、OfficeHelp常用方法辅助扩展类等就不在此一一列举了。
2.2.6 ORM的分析及与Xml、JSON、EString的交互
1、ORM的分析
ORM通过对开发人员隐藏SQL细节可以大大提高生产力。然而很不幸,“ORM”和“性能问题”常常一起出现,它容易产生一些未被发现的荒谬查询,虽然几率不是很高,但万一出现,如果没有好的分析方案,也是极为头疼的事。通常情况下,数据库管理员可以通过如交叉引用有问题的存储过程或其它途径来查找问题代码。但是,ORM依赖于动态生成的SQL,便很难这么做了。所以,需要一些有效的ORM分析方法。该工具组件System.Database.DbCore提供了DbCore.GetCurrentCommandText等静态方法可以在任何执行ORM操作时分析当前执行的SQL语句,这样在任何时候当出现异常时可查看当前执行的SQL,如果SQL正常可排除不是ORM的问题,否则说明所编写的代码结构中出现了问题。
2、与XML的交互
工具生成的实体提供ToXml和FromXml两个方法及相应的重载和补充方法,可以方便实体对象与XML内容直接相互转换。
示例代码如下所示:
TSTENTITY entity = new TSTENTITY(1); //得到主键为1的实体对象信息 TSTENTITY entity_ = new TSTENTITY();//仅实例化实体对象 string sTst = entity.ToXml(); entity.ToXml(@"C:\tst.xml", Encoding.UTF8, Formatting.Indented); entity.ToXml_(@"C:\tst1.xml", Encoding.UTF8, Formatting.Indented); entity_ = entity_.FromXml(sTst); entity_ = new TSTENTITY(); entity_ = entity_.FromXmlFile(@"C:\tst.xml"); entity_ = new TSTENTITY(); entity_ = entity_.FromXmlFile(@"C:\tst1.xml"); |
同样实体集也提供ToXml和FromXml及相应的重载和补充方法,方便实体集对象与XML内容直接相互转换。
示例代码如下所示:
employeeS entitys1 = new employeeS(true); //获取员工对象的所有信息到实体集对象 employeeS entitys2 = new employeeS();//仅实例化实体集对象 employeeS entitys3 = new employeeS(); employeeS entitys4 = new employeeS(); string strXml = entitys1.ToXml(); entitys2 = entitys2.FromXml(strXml); //从Xml内容中加载对象 strXml = entitys1.ToXml(Formatting.Indented); entitys3 = entitys3.FromXml(strXml); //从Xml内容中加载对象 string strFile = "temp.xml"; entitys1.ToXml_(strFile, Encoding.UTF8, Formatting.Indented); entitys4 = entitys4.FromXmlFile(strFile); //从Xml文件中加载对象 |
3、与JSON的交互
工具生成的实体提供ToJSON和FromJSON两个方法及相应实体集方法,可以方便实体对象、实体集对象与JSON内容直接相互转换。
示例代码如下所示:
employee e1 = new employee("A-C71970F");//得到主键为A-C71970F的对应数据 employee e2 = new employee("asd");//没有对应数据 employeeS es = new employeeS(true);//获取全部数据 employee entity1; employeeS entitys; employeeS entitys1; employeeS entitys2; entity1 = new employee(); string json1 = e1.ToJSON();//将实体信息转化为JSON文本 entity1 = entity1.FromJSON(json1);//从JSON文本中转化到实体 entitys = new employeeS(); entitys1 = new employeeS(); entitys2 = new employeeS(); entitys.Add(e1); entitys.Add(e2); string json3 = entitys.ToJSON(); entitys1 = entitys1.FromJSON(json3); //通用用法 entitys2.FromJSON(json3); //实体集专用用法 entitys1 = new employeeS(); entitys2 = new employeeS(); json3 = es.ToJSON(); entitys1 = entitys1.FromJSON(json3); //通用用法 entitys2.FromJSON(json3); //实体集专用用法 |
4、与String(即EString)的交互
工具生成的实体提供ToString和FromString两个方法及相应实体集方法,可以方便实体对象、实体集对象与String内容直接相互转换。
示例代码如下所示:
employee e1 = new employee("A-C71970F");//得到主键为A-C71970F的对应数据 employeeS es = new employeeS(true);//获取全部数据 employee entity1 = new employee(); employeeS entitys1 = new employeeS(); employeeS entitys2 = new employeeS(); string str1 = e1.ToString();//转化为字符串文本 entity1 = entity1.FromString(str1);//从字符串文本中实例化到实体 string strEntitys = es.ToString(); entitys1 = entitys1.FromString(strEntitys);//实体集通用用法 entitys2.FromString(strEntitys);//实体集专用用法 |
注:EString是针对实体/集(亦即一维/二维数据)设计的,格式为键值对的形式出现,以键盘不能直接输入的单个生僻字符’┋’为分割符,对于集合类,以’┋┋’(即连续两个’┋’)为分割符(示例=>name┋value1┋┋name┋value2)。
2.2.7 LINQ的支持
1、Linq ToEntitys
实体集对象默认是可以支持Linq的,只是Linq是在.NET Framework 3.5 中出现的技术,所以在创建新项目的时候必须要选3.5或者更高版本,才能使用。当前项目基本上都是.Net3.5或以上版本的,这里也把这部分示例代码加上:
// Entitys Linq 的查询示例 net framework 3.5/4.0/及其以上 TSTENTITYS entitys = new TSTENTITYS(); TSTENTITY entity = new TSTENTITY(); entity.TSTTXT = "aa"; entitys.Add(entity); entitys.Add(newTSTENTITY() { TSTTXT="bb" }); var qq = entitys.OfType<TSTENTITY>(); var pp =from pin qqwhere p.TSTTXT=="aa"select p; foreach (var pin qq) { string s = p.TSTTXT; //两个结果分别是:aa、bb } foreach (var pin pp) { string s = p.TSTTXT; //筛选后的结果:aa } |
可以看出关键是这句entitys.OfType<TSTENTITY>(),OfType是System.Linq下的方法,需要引用该命名空间。选择3.5或更高版本的.NET Framework之后,创建的新项目中会自动包含System.Linq的命名空间(using System.Linq;)。
2.2.8轻量级日志组件
经常,客户说报错的时候,作为开发人员,基本上不可能到第一现场观察错误提示,这也导致了异常定位非常的困难,大大增加了维护的成本。使用日志后,一旦某个页面出错,即使客户没有反馈,系统也能记录下来,为管理员修正错误以及优化系统提供足够丰富的信息。ECG同样也提供了轻量级的简单日志组件。
1、简单日志配置
配置说明如下:
配置节关键字 |
配置说明 |
_LOG_LEVEL_ |
日志级别配置节关键字,配置内容可为:DEBUG|INFO|WARN|ERROR|FATAL (默认DEBUG) |
_LOG_FILE_ |
日志文件配置节关键字配置内容:日志文件路径+文件名(不含文件扩展名)(默认SimpleLogger) |
_LOG_FILE_MAX_SIZE_ |
日志文件配置节关键字,日志文件的最大长度(单位:字节)(不得小于1024字节,即1K)(默认1M = 1*1024*1024=1048576) 当日志文件超过该大小时会自动重建。 |
_LOG_SPLIT_ |
日志文件是否按命名空间分开存储的配置节关键字: TRUE|FALSE (默认FALSE) |
_LOG_NS_MAXLENGTH_ |
当日志文件按命名空间分开存储时(即_LOG_SPLIT_=TRUE),命名空间截取的最大长度(该值必须大于0,方有效),默认命名空间全称 |
_LOG_NS_DIV_COUNT_ |
当日志文件按命名空间分开存储时(即_LOG_SPLIT_=TRUE),命名空间长度最大截取到第几分段(以“.”分割)(该值必须大于0,方有效),默认命名空间全称 |
_LOG_ASYN_ |
异步写入日志标示,TRUE:新启线程采用日志队列方式异步写入,FALSE:直接写入日志文件(默认FALSE) |
_LOG_ASYN_WAIT_ |
异步写入时,当日志队列为空的等待毫秒数(必须大于等于0,为0则没有等待时间(较耗资源);可不配置,默认100毫秒)(_LOG_ASYN_必须配置TRUE,该项才起作用) |
_LOG_ASYN_THREAD_BACKGROUND_ |
异步写入线程是前台线程还是后台线程(对应Thread.IsBackground属性),TRUE后台线程,FALSE前台线程(默认FALSE)(_LOG_ASYN_必须配置TRUE,该项才起作用) |
这里的配置节关键字是区分大小写的,要求全部大写,所有配置项都有默认值,不需要全部配置,可根据实际需要进行选择。配置项在系统首次加载时进行初始化,再次修改配置项需重启应用程序。
日志路径默认为运行程序所在运行路径,对于Web程序,若在VisualStudio下web.config中没有配置_LOG_FILE_指定到具体路径下,则会在对应的IDE目录下(以VS2005为例,在Microsoft Visual Studio8\Common7\IDE\);建议这里明确填写具体完整的绝对路径(例如:C:\Log\SimpleLogger,日志记录到C:\Log\目录下(如果目录不存在则会自动创建),日志文件名以SimpleLogger为前缀开头);日志文件的扩展名为(.log)。
2、简单日志的使用
using System.Logger; |
SimpleLogger logger =SimpleLogger.GetInstance(); logger.Debug("环境打印出的调试日志"); logger.Info("环境打印出的信息日志"); logger.Warn("环境打印出的警告日志"); logger.Error("环境打印出的一般错误日志"); logger.Fatal("环境打印出的致命错误日志"); |
日志组件位于System.Database.dll中,项目引用命名空间(System.Logger)即可,日志组件提供五种级别的日志记录(DEBUG|INFO|WARN|ERROR|FATAL),最低DEBUG,最高FATAL,当配置的级别大于等于对应级别时,会自动记录日志,如:当前配置_LOG_LEVEL_值为ERROR时,DEBUG|INFO|WARN三种级别日志将直接跳过不记录,ERROR|FATAL级别的日志会记录。SimpleLogger提供了单实例接口SimpleLogger.GetInstance(),支持多线程并发操作,使用时可直接调用获取日志实例对象。同时各级别日志记录接口(Debug| Info Warn| Error| Fatal)均有不同重载方式。
3结束语
理论的实现总是从简单到复杂,覆盖所有可能,实际应用则需要结合实际从复杂到简单,凡是要灵活变通使用,化复杂为简单,将复杂的东西以简单的方式处理。
尽管我们注入大量心血,但不足之处在所难免,有待进一步完善,敬请来信交流(lxchutao@163.com)、批评斧正!
4 相关下载地址
http://www.cnblogs.com/lxchutao/archive/2011/06/01/2065977.html
http://files.cnblogs.com/lxchutao/EntitysCodeGenerate.rar
http://www.cnblogs.com/lxchutao
http://www.skycn.com/soft/53715.html
http://download.enet.com.cn/html/030212009031901.html
http://www.newhua.com/soft/98941.htm
http://www.duote.com/soft/32643.html
http://www.crsky.com/soft/25626.html
http://download.csdn.net/source/3030634
http://qun.qq.com/air/#60873348/share
http://download.enet.com.cn/eblog/blog/htm/uid_21280.html
转载于:https://www.cnblogs.com/zhaoyx/articles/3335654.html
ORM框架-VB/C#.Net实体代码生成工具(EntitysCodeGenerate)【ECG】4.5相关推荐
- ORM框架-VB/C#.Net实体代码生成工具(EntitysCodeGenerate)【ECG】4.6
摘要:VB/C#.Net实体代码生成工具(EntitysCodeGenerate)[ECG]是一款专门为.Net数据库程序开发量身定做的(ORM框架)代码生成工具,所生成的程序代码基于OO.ADO.N ...
- MongoDB的orm框架
首先spring自带了mongodb的orm,spring data mongodb,但是这个框架非常难用,最令人抓狂的是每个文档都要带一个 _class 字段,因为这个是string的,所以占用不少 ...
- ORM框架-工具-产品开发之四 开发代码生成器 Template Studio Development (一)
今天进入ORM工具开发系列的代码生成工具的开发.现在流行的代码生成工具,一般是基于模板的.T4,Code Smith在基于模板的代码生成方面相当流行.ORM工具,需要从不同的数据库中读取元数据,调用代 ...
- 如何提高程序员人效?代码生成工具/框架
image.png 最近事情太多,很久没有更新简书,突然想起如何提高程序员人效这个问题,就推荐一篇代码生成工具/框架的文章. http://www.cnblogs.com/skyme/archive/ ...
- ssm框架通用代码生成工具
ssm框架通用代码生成工具 网上搜了一下,没找到什么很顺手的工具.想自己写一个.做了几天有点小成果.发上来看看有没有同行需要,或者大家有什么更好的工具,可以共享一下.谢谢了. 1.由于excel用的更 ...
- 代码生成工具更新--快速生成Winform框架的界面项目
在之前版本的代码生成工具Database2Sharp中,由于代码生成都是考虑Winform和Web通用的目的,因此Winform界面或者Web界面都是单独生成的,在工具中生成相应的界面后,复制到项目里 ...
- 基于mybatis-generator代码生成工具改(链式方法实体版)
概述 一直以来使用原生mybatis-generator的我发现有一个地方很不方便,即它生成的实体类的set方法返回值是void,而目前比较流行的则是链式set的写法,即set方法返回值不再是void ...
- ASP.NET MVC学习---(一)ORM框架,EF实体数据模型简介
现如今 对象关系映射(ORM)框架 被大量的使用于企业级应用的开发 为什么要使用ORM? ADO.NET操作数据库不好吗? 我们可以仔细想想 当我们使用ADO.NET操作数据库的时候 我们需要先获取连 ...
- 小巧优美的ORM框架-doodads
关于.net下的ORM框架,大家最为耳熟的可能就是NHibernate了,当然,很多公司正在使用自己开发的ORM框架,笔者至少见过3家不同公司的ORM框架,其实都是大同小异,借助于codesmith. ...
最新文章
- 在Windows下编译FFmpeg详细说明
- 过程或函数的副作用是_Python函数和函数式编程(两万字长文警告!一文彻底搞定函数,建议收藏!)...
- 这位数字艺术的开拓者,通过计算机算法成就了新的艺术表达方式
- 为什么说Serverless是云的未来?
- C++11 并发指南六( atomic 类型详解二 std::atomic )
- mysql别人的框架_MySQL逻辑架构
- bzoj 3238: [Ahoi2013]差异(后缀数组+单调栈)
- [cocos2dx笔记015]关于cocos2dx Button三种状态说明
- POJ3253-Fence Repair
- Mobile开发之meta篇
- Android音视频——H.264帧码流(SODB、RBSP、EBSP)浅析
- 2022全国智慧医院建设大会
- 【PS】如何简单的处理带晒伤皮肤的婚纱照?红斑/脱皮/减淡红色
- C语言 | 条件运算符
- 你真的了解活跃用户吗?
- vue中使用第三方阿里巴巴矢量图标库,并修改图标大小
- pyspark steaming常规语句及操作
- 记一次收到QQ邮箱钓鱼邮件经历
- 2021-08-17
- Android开发--WIFI输入密码Dialog的实现