ORM框架-VB/C#.Net实体代码生成工具(EntitysCodeGenerate)【ECG】4.6
摘要: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.6
目 录
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半自动化Mapping-SQL
1、Mapping-SQL介绍
2、Mapping-SQL使用
2.2.5 DbCore+SQL/存储过程
1、DbCore+SQL
2、DbCore+存储过程
3、DbCore执行SQL/存储过程的快捷用法
2.2.6 Extend辅助扩展功能
1、TableHelp辅助扩展
2、CommonHelp常用方法扩展
2.2.7 ORM的分析及与Xml、JSON、EString的交互
1、ORM的分析
2、与XML的交互
3、与JSON的交互
4、与String(即EString)的交互
2.2.8 LINQ的支持
1、LinqTo Entitys
2.2.9 轻量级日志组件
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 =new DEPT(); |
此处以该对象来做阐述。
1、获取一个实体对象信息
实体的操作默认以主键为准,对单个实体信息的获取可简单如下实现:
entity.DEPTNO = 50; entity = entity.GetEntity(); |
返回主键字段DEPTNO=50的对象,若数据库中没有对应的记录则返回null。DEPT表的主键字段是DEPTNO,同时对联合主键也是支持的,下文同此;GetEntity同时提供其它指定条件的重载,也可以使用GetEntityByEntityCondition,当指定条件有多个记录符合时只返回首条记录;返回多条记录可使用GetDataTable方法。
在3.3版本之后也可通过多个构造函数来获取单个实体对象的信息等:
DEPT entity =new DEPT(50); //通过主键字段条件获取实体对象 DEPT entity =new DEPT(newstring[] { "DEPTNO" },new object[] { 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 =new DEPTS(true); //获取所有部门信息 EMPS entitys1 =new EMPS(newstring[] { "DEPTNO" },new object[] { 50 }); |
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,这里只是用来展示之用。
System.Database.DbCore类提供Select方法及其相应的重载,以SqlServer自带的pubs库为例,可见如下代码:
DataSet dst =new DataSet(); |
DataSet dst = dbCore.SelectAll().From("sales").ExecuteDataSet(); |
DataSet dst = dbCore.SelectAll().From(SALESColumn.TableName).ExecuteDataSet(); |
DataSet dst = |
DataSet dst = |
DataSet dst = dbCore.SelectAll().From(newSALES()).ExecuteDataSet(); |
DataSet dst =new DataSet();DataSet dst1= new DataSet(); |
dst = dbCore.SelectAll().From().JoinInner("sales","stor_id ", "stores","stor_id") |
dst = dbCore.SelectAll().From().JoinInner(SALESColumn.stor_id,STORESColumn.stor_id) |
dst = dbCore.SelectAll().From().JoinLeft("sales","stor_id ", "stores","stor_id") |
dst = dbCore.SelectAll().From().JoinLeft(SALESColumn.stor_id,STORESColumn.stor_id) |
dst = dbCore.SelectAll().From().JoinRight("sales","stor_id ", "stores","stor_id") |
dst = dbCore.SelectAll().From().JoinRight(SALESColumn.stor_id,STORESColumn.stor_id) |
dst = dbCore.SelectAll().From().JoinFull("sales","stor_id ", "stores","stor_id") |
dst = dbCore.SelectAll().From().JoinFull(SALESColumn.stor_id,STORESColumn.stor_id) |
DataSet dst =new DataSet(); |
dst = dbCore.SelectAll().From().JoinInner("sales","stor_id ", "stores","stor_id") |
dst1 = dbCore.SelectAll().From().JoinInner(SALESColumn.stor_id,STORESColumn.stor_id) |
dst = dbCore.SelectAll().From().JoinInner("sales","stor_id ", "stores","stor_id") |
dst1 = dbCore.SelectAll().From().JoinInner(SALESColumn.stor_id,STORESColumn.stor_id) |
dst = dbCore.SelectAll().From("sales").FromTable("stores") .Where().ConditionColumnAndEqual("sales","stor_id", "stores","stor_id"). |
dst1 = dbCore.SelectAll().From(SALESColumn.TableName).FromTable(STORESColumn.TableName) |
这里切换到Oracle数据库,以Oracle自带的scott用户为例,先看如下代码:
DataSet dst =new DataSet(); |
dst = dbCore.SelectAll().From(entity) |
dst = dbCore.SelectAll().From(entity) |
dst = dbCore.SelectAll().From(entity) |
dst = dbCore.SelectAll().From(EMPColumn.TableName) |
这里同样以Oracle自带的scott用户为例,先看如下代码:
DataSet dst =new DataSet(); |
dst = dbCore.Select().SelectColumnMaxValue(EMPColumn.EMPNO) |
dst1 = dbCore.Select().AddMax(EMPColumn.EMPNO) |
dst = dbCore.Select().SelectColumn(EMPColumn.DEPTNO).SelectColumn(EMPColumn.SAL) .GroupBy(EMPColumn.DEPTNO).Column(EMPColumn.SAL) |
dst1 = dbCore.Select().Add(EMPColumn.DEPTNO).Add(EMPColumn.SAL) .AddMax(EMPColumn.EMPNO).AddMin(EMPColumn.EMPNO).AddAvg(EMPColumn.EMPNO) |
dst = dbCore.Select().SelectColumn(EMPColumn.DEPTNO).SelectColumn(EMPColumn.SAL) |
dst1 = dbCore.Select().Add(EMPColumn.DEPTNO).Add(EMPColumn.SAL) |
dst = dbCore.Select().SelectColumn(EMPColumn.DEPTNO).SelectColumn(EMPColumn.SAL) |
dst = dbCore.Select().SelectColumn(EMPColumn.DEPTNO).SelectColumn(EMPColumn.SAL) |
dst = dbCore.Select().SelectColumn(EMPColumn.DEPTNO).SelectColumn(EMPColumn.SAL) |
SELECT emp.deptno, emp.sal, |
和直接编写SQL很相似,省去许多代码量,且可读性高,维护也方便。
(1)-(5)介绍的没有加入事务处理功能,下面介绍结合事务的使用,先看如下代码:
DataSet dst = new DataSet(); try { dbCore.Open();//--打开数据库连接 dbCore.BeginTransaction();//开始事务 int intRecordCount = dbCore.DeleteFrom(EMPColumn.TableName).ExecuteNonQuery(); dst = dbCore.SelectAll().From(EMPColumn.TableName).ExecuteDataSet(); dbCore.RollbackTransaction();//回滚撤销事务 //dbCore.CommitTransaction();//提交事务 dst1 = dbCore.SelectAll().From(newEMP()).ExecuteDataSet(); dbCore.Close();//--关闭数据库连接 } catch (Exception ex) { if (dbCore != null) dbCore.Close(); MessageBox.Show(ex.Message); } |
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 { dst = dbCore.SelectAll().From(newEMP()).ExecuteDataSet(); 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) dst = dbCore.SelectAll().From(EMPColumn.TableName).ExecuteDataSet(); intRecordCount = dbCore.DeleteFrom(newEMP()).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; } |
用法同上,不再详细赘述,这里换张表以作区别,可见示例代码,如下所示:
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; } |
<?xmlversion="1.0"encoding="utf-8" ?> <sqlmap> <!--关键字 id区分大小写 --> <!-- query all information from table t_demo by condition. Note: <[ ... ]>--> <sqlid="lxchutao.mapingsql.demo.ui.query.test"> <content> <![CDATA[ SELECT T.* FROM T_DEMO T WHERE 1=1 <[ AND T.C_NAME=:C_NAME ]><[ AND T.C_IDCARD LIKE :C_IDCARD ]> ORDER BY T.C_NAME ]]> </content> </sql> </sqlmap> |
这里是Oracle的写法,可以看出与SQL唯一的区别就是动态参数条件加了个<[…]>标记,其它同SQL语法一样。
Mapping-SQL配置信息建议在系统初始化启动时统一加载到内存,执行时以id进行获取。即在全局应用程序类Global.asax的Application_Start执行以下代码:
//程序启动前默认加载所有Naming-sql文件到内存 string defaultPath = HostingEnvironment.ApplicationPhysicalPath+ "config\\db\\"+ DbFileName() + "\\"; foreach (string filenamein Directory.GetFiles(defaultPath)) { if (filename.ToLower().EndsWith("maping-sql.xml")) { MapingSqlUtil.Load(filename); } } |
using System.Data; using System.Database; namespace LXChuTao.MapingSQL.Demo.BLL { public class Demo { ///<summary> ///查询示例:根据条件MapingSQL会自动匹配查询动态条件(<[ ... ]>)(没有加这个前后标记的会一直参与查询执行) ///当对应的参数存在有值时,该条件才会参与查询(增删改参数条件语句于此类似) ///</summary> ///<param name="name">精确匹配参数名称</param> ///<param name="idCard">模糊匹配IDCard</param> ///<returns>查询结果集</returns> public DataSet GetT_DemoByCondition(string name,string idCard) { using (DbCore dbCore= DBHelper.GetNewDbCore()) { DBCommandWrapper cmd= dbCore.GetMapingSqlCommandWrapper("lxchutao.mapingsql.demo.ui.query.test");//只需MapingSQL的id if (!string.IsNullOrEmpty(name)) cmd.AddInParameter("c_name",DbType.AnsiString, name); if (!string.IsNullOrEmpty(idCard)) cmd.AddInParameter("c_idcard",DbType.AnsiString,"%" + idCard + "%"); return dbCore.ExecuteDataSet(cmd); } } } } |
DbCore dbCore =new DbCore(DatabaseType.Oracle, “OracleConnectionString”); |
DbCore dbCore =new DbCore(DatabaseType.ODPNet, “OracleConnectionString”);//ODP.NET方式 |
DbCore dbCore =new DbCore(DatabaseType.SqlServer, “SqlServerConnectionString”); |
DbCore dbCore =new DbCore(DatabaseType.Sybase, “SybaseConnectionString”); |
DbCore dbCore =new DbCore(DatabaseType.DB2, “DB2ConnectionString”); |
DbCore dbCore =new DbCore(DatabaseType.MySql, “MySqlConnectionString”); |
DbCore dbCore =new DbCore(DatabaseType.SQLite, “SQLiteConnectionString”); |
DbCore dbCore =new DbCore(DatabaseType.PostgreSQL, “PostgreSQLConnectionString”); |
DbCore dbCore =new DbCore(DatabaseType.Access, “AccessConnectionString”); |
DbCore dbCore =new DbCore(DatabaseType.Dm, “DmConnectionString”); |
DbCore dbCore =new DbCore(DatabaseType.Informix, “InformixConnectionString”); |
DbCore dbCore =new DbCore(DatabaseType.Firebird, “FirebirdConnectionString”); |
DbCore dbCore =new DbCore(DatabaseType.MaxDB, “MaxDBConnectionString”); |
DbCore dbCore =new DbCore(DatabaseType.OleDb, “OleDbConnectionString”); |
DbCore dbCore =new DbCore(DatabaseType.Odbc, “OdbcConnectionString”); |
下面看一段适合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();//关闭数据库连接 |
对专有数据库命令也可以转化为指定数据库命令来使用,这样可针对该数据库特性使用更多的方法,如Oracle、SqlServer的命令转化可像下列代码来转化:
OracleCommandWrapper cmd = dbCore.GetSqlStringCommandWrapper(strSql)as OracleCommandWrapper; |
SqlCommandWrapper cmd = dbCore.GetSqlStringCommandWrapper(strSql)as SqlCommandWrapper; |
…… |
DataSetdst = dbCore.ExecuteDataSet(strSql); DataTable dtbl = dbCore.ExecuteDataSet(strSql).Tables[0]; |
catch (Exception ex) { if (dbCore != null) { if (dbCore.IsTransaction) { dbCore.RollbackTransaction();//如果已经开始事务,则回滚事务 } dbCore.Close(); } throw ex; } |
最后再说一个System.Database.DbCoreConnectLimit.AllDBMaxConnectionCount,可以设置数据库打开的最大连接数目,默认不受限制。
DBCommandWrapper cmd = dbCore.GetStoredProcCommandWrapper("[包名.]存储过程名"); dbCore.ExecuteNonQuery(cmd); |
OracleCommandWrapper cmd = dbCore.GetStoredProcCommandWrapper("[包名.]存储过程名")as OracleCommandWrapper; //cmd.AddOutParameter(... //cmd.AddParameter(... //cmd.AddCursorOutParameter(... dbCore.ExecuteDataSet(cmd); |
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")as OracleCommandWrapper; //cmd.AddInParameter( //cmd.AddOutParameter( //cmd.AddParameter( //cmd.AddCursorOutParameter( count = dbCore.ExecuteNonQuery(cmd); cmd = dbCore.GetStoredProcCommandWrapper("storedProcedure.NameB")as OracleCommandWrapper; //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; } |
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.7 ORM的分析及与Xml、JSON、EString的交互
工具生成的实体提供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文件中加载对象 |
工具生成的实体提供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); //实体集专用用法 |
工具生成的实体提供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);//实体集专用用法 |
// 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 p in qq where p.TSTTXT =="aa" select p; foreach (var pin qq) { string s = p.TSTTXT; //两个结果分别是:aa、bb } foreach (var pin pp) { string s = p.TSTTXT; //筛选后的结果:aa } |
配置节关键字 |
配置说明 |
_LOG_LEVEL_ |
日志级别配置节关键字,配置内容可为:DEBUG|INFO|WARN|ERROR|FATAL (默认ERROR) |
_LOG_FILE_ |
日志文件配置节关键字配置内容:日志文件路径+文件名(不含文件扩展名)(如果配置节_LOG_FILE_未配置,则取环境变量"_LOG_ENV_PATH_FILE_"对应的配置值;如果该环境变量值也未配置则取环境变量%TEMP%临时目录对应的目录下;如果环境变量%TEMP%也未配置,则取运行程序所在运行路径,默认文件名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,该项才起作用) |
这里的配置节关键字是区分大小写的,要求全部大写,所有配置项都有默认值,不需要全部配置,可根据实际需要进行选择。配置项在系统首次加载时进行初始化,再次修改配置项需重启应用程序。
using System.Logger; |
SimpleLogger logger =SimpleLogger.GetInstance(); logger.Debug("环境打印出的调试日志"); logger.Info("环境打印出的信息日志"); logger.Warn("环境打印出的警告日志"); logger.Error("环境打印出的一般错误日志"); logger.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.duote.com/soft/32643.html
http://www.crsky.com/soft/25626.html
http://www.onlinedown.net/soft/98941.htm
http://download.enet.com.cn/eblog/blog/htm/uid_21280.html
http://download.enet.com.cn/html/030212009031901.html
http://download.csdn.net/source/3030634
http://download.csdn.net/source/3179741
http://qun.qq.com/air/#60873348/share
ORM框架-VB/C#.Net实体代码生成工具(EntitysCodeGenerate)【ECG】4.6相关推荐
- ORM框架-VB/C#.Net实体代码生成工具(EntitysCodeGenerate)【ECG】4.5
引言 内容 ORM框架的实现VBCNet实体代码生成工具EntitysCodeGenerate 在开发中的实际应用 结束语 相关下载地址 摘要:VB/C#.Net实体代码生成工具(EntitysCod ...
- 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. ...
最新文章
- win10下使用pycharm调试wsl的代码
- 【剑指offer-Java版】33把数组排成最小的数
- Flutter 2 源码阅读
- HDU - 5790 Prefix(主席树+字典树)
- scala常用spark的pom.xml与读取csv为rdd到最终join操作
- 技术博客么?开始每天一更
- 用PHP实现多级树型菜单
- 随机化算法-数值随机化算法
- armhf php环境搭建,armel、armhf 和 arm64 区别选择
- c语言 运行库 下载,Visual C++运行库合集
- postgresql 不区分大小写 模糊查询
- 基于安卓系统(android)记事本APP管理系统设计与实现
- mysql 幂函数_MySQL-函数
- wpa_supplicant-2.6 君正平台(Zeratul )编译 支持WPS功能
- c#设计一个Windows应用程序,模拟一个简单的银行账户管理系统。完成“创建账A款”“存款”和“查询余额”的模拟操作。程序功能如下:
- 腾讯地图 多个异步script互相依赖加载问题
- 【机器学习】多项式回归
- 计算机服务器机房 消防灭火,服务器机房消防系统和维护
- Karl Guttag:从AWE 2022光学技术展示看未来AR趋势
- mt6582 pwm