EMStudio系列教程5--EMLib框架之Eql
从本章开始将使用两章节的篇幅来介绍EMLib框架,这一章介绍Eql相关的内容。在介绍Eql内容之前需要做一个准备工作,那就是开发环境的配置,这是一个非常简单的工作。

一.配置开发环境
由于笔者使用的是VS2010,所以用VS2010作为开发环境来介绍,但是所讲述的内容同样适用于VS2008。首先创建一个新的工程,语言是C#,类型是Windows Form Application,工程名字和保存目录位置任意。

鼠标右击工程节点,在弹出菜单中选择Add—>Existing Item…,打开生成源代码所在的目录。先添加EDModel.Biz.EDExtern文件夹中的EDModel.cs文件,注意是引用添加。然后添加EDModel.Biz.EDCustom文件夹中的文件,注意是复制添加,即直接点击Add按钮就。接着引用EMLib动态链接库。EMLib.dll文件在EMStudio安装目录的EMLib文件夹下。鼠标右击References节点,在弹出菜单中选择Add Reference…,打开EMStudio安装目录,再打开EMLib文件夹,添加EMLib.dll文件。

最后一步是在源代码文件中添加命名空间,打开Form.cs文件,在文件头部加入EMLib命名空间的引用和生成的源代码所在命名空间的引用,如下所示:
  
                                        using EMLib.Entity;
                                        using EMLib.EqlLib;
                                        using EMLib.Global;
                                        using EMLib.Orm;
                                        using MyNamespace;
                                        
至此开发环境就配置完成了。

二.Eql基本语句的使用
Eql的全称是实体查询语言(Entity Model Studio),这是一种基于宿主语言的编程接口。允许开发者以方法连续调用的方式,非常方便和灵活的构造出各种复杂程度的语句对象。其开发效率明显高于传统字符串拼接构造Sql语句的方式。同时基于Eql语句对象,可以使用EMLib完成所有强大的ORM功能。以下是查询,更新,插入,删除语句的演示代码,读者可以自行输入源代码完成实际的Eql语句对象的构造。

查询语句
  
                                        EqlSelect stmt = Eql.Select(MyContext.Company).
	                                        From(MyContext.Company).
	                                        Where(MyContext.Company.ID > 10);
                                        
更新语句
  
                                        EqlUpdate stmt = Eql.Update(MyContext.Company).
	                                        Set(MyContext.Company.CompanyName, "MyCompany").
	                                        ThenSetNull(MyContext.Company.Address).
	                                        From(MyContext.Company).
	                                        Where(SqlLib.Len(MyContext.Company.Address) < 5);
                                        
插入语句
  
                                        EqlInsert stmt = Eql.InsertInto(MyContext.Company).
	                                        Set(MyContext.Company.CompanyName, "MyCompany").
	                                        ThenSetNull(MyContext.Company.Address);
                                        
删除语句
  
                                        EqlDelete stmt = Eql.Delete(MyContext.Company).
	                                        From(MyContext.Company).
	                                        Where(SqlLib.Len(MyContext.Company.Address) < 5);
                                        
三.从Eql语句对象获得Sql语句文本
EMLib直接支持从Eql语句对象获得对应等价文本的功能,举例代码如下:
  
                                        EMContext context = MyContext.CreateContext(pathModel, pathLic);
                                        EqlSelect stmt = Eql.Select(MyContext.Company).
	                                        From(MyContext.Company).
	                                        Where(MyContext.Company.ID > 5);
                                        EMStmeHelper helper = new EMStmeHelper(context);
                                        EMStmtUnit txtSql = helper.EqlBuildSqlText(stmt);
                                        
StmtTextUnit有两个属性,一个是TextWithParam,这个就是对应的等价文本;另一个是Parms,这个是语句文本中用到的参数的对象。可以看到上述代码为了得到Sql文本首先生成了一个EMContext的对象,调用的是MyContext中方法。这个类和方法是自动生成的,在EDModel.cs文件中。该方法的第一个参数是模型文件所在位置。模型文件在生成源代码时自动生成,在EDModel.Biz.EDExtern文件夹中,是一个xml文件。第二个参数是EMLib的许可证文件。在EMStudio通过注册后该文件会被自动生成,位置在EMStudio安装目录的EMLib文件夹中,是一个dat文件。关于EMContext对象的内容,在下一章节EMLib框架之Orm中还会进一步详细介绍。

用EqlBuildSqlText可以为上面四个语句对象生成对应的等价文本,如下所示:

查询语句:
  
                                        SELECT Company.ID, Company.Address, Company.CompanyName, 'Company' AS CurrEntityTag 
	                                        FROM Company 
	                                        WHERE Company.ID > @ParamName1
                                        
更新语句:
  
                                        UPDATE Company SET 
	                                        Company.CompanyName = @ParamName1, 
	                                        Company.Address = NULL FROM Company 
	                                        WHERE Len(Company.Address) < @ParamName2
                                        
插入语句
  
                                        INSERT INTO Company 
	                                        (Company.CompanyName, Company.Address) 
	                                        VALUES 
	                                        (@ParamName1, NULL)
                                        
删除语句
  
                                        DELETE Company 
	                                        FROM Company 
	                                        WHERE Len(Company.Address) < @ParamName1
                                        
四.Eql对多态的支持
Eql对多态的支持是非常彻底而完整的,从语句结构和ORM功能角度来说,这种对多态性的支持是完备的。下面简单的演示两个例子来介绍这种对多态性的支持,更为详细的介绍在下一章节中完成。构造如下的Eql语句对象:
  
                                        EqlSelect stmt = Eql.Select(MyContext.BaseEntityPoly).
	                                        From(MyContext.BaseEntityPoly).
	                                        Where(MyContext.BaseEntityPoly.ID > 10);
                                        
这是一个对BaseEntity实体执行多态查询的Eql语句对象,其对应的等价文本如下:
  
                                        SELECT BaseEntity.ID, BaseEntity.BaseName, BaseEntity.CurrEntityTag 
	                                        FROM (SELECT BaseEntity.ID, BaseEntity.BaseName, 'BaseEntity' AS CurrEntityTag 
		                                        FROM BaseEntity UNION ALL 
	                                                SELECT SubEntity.ID, SubEntity.BaseName, 'SubEntity' AS CurrEntityTag 
		                                        FROM SubEntity) AS BaseEntity 
	                                        WHERE BaseEntity.ID > @ParamName1
                                        
构造如下的删除语句:
  
                                        EqlDelete stmt = Eql.Delete(MyContext.BaseEntityPoly).
	                                        From(MyContext.BaseEntityPoly).
	                                        Where(MyContext.BaseEntityPoly.ID > 10);
                                        
这表示要对实体BaseEntity执行多态删除,也就是要删除BaseEntity及其子类的满足条件的数据。其对应的等价文本就是两条删除语句:
  
                                        DELETE PolySubject 
	                                        FROM (SELECT BaseEntity.ID, BaseEntity.BaseName, 'BaseEntity' AS CurrEntityTag 
		                                        FROM BaseEntity UNION ALL 
	                                                SELECT SubEntity.ID, SubEntity.BaseName, 'SubEntity' AS CurrEntityTag 
		                                        FROM SubEntity) AS BaseEntity, BaseEntity AS PolySubject 
	                                        WHERE BaseEntity.ID > @ParamName1 AND 
	                                                BaseEntity.CurrEntityTag = 'BaseEntity' AND 
	                                                PolySubject.ID = BaseEntity.ID

                                        DELETE PolySubject 
	                                        FROM (SELECT BaseEntity.ID, BaseEntity.BaseName, 'BaseEntity' AS CurrEntityTag 
		                                        FROM BaseEntity UNION ALL 
	                                                SELECT SubEntity.ID, SubEntity.BaseName, 'SubEntity' AS CurrEntityTag 
		                                        FROM SubEntity) AS BaseEntity, SubEntity AS PolySubject 
	                                        WHERE BaseEntity.ID > @ParamName1 AND 
	                                                BaseEntity.CurrEntityTag = 'SubEntity' AND 
	                                                PolySubject.ID = BaseEntity.ID
                                        
五.子查询
如下所示是一个子查询的例子:
  
                                        EqlDelete stmt = Eql.Delete(MyContext.Company).
	                                        From(MyContext.Company).
	                                        Where(MyContext.Company.ID.In(Eql.Select(MyContext.Employee).
		                                        From(MyContext.Employee).
		                                        Where(MyContext.Employee.ID < 10)));
                                        
为了方便阅读和理解也可以拆分写成如下的形式:
  
                                        EqlSelect stmtSub = Eql.Select(MyContext.Employee).
	                                        From(MyContext.Employee).
	                                        Where(MyContext.Employee.ID < 10);

                                        EqlDelete stmt = Eql.Delete(MyContext.Company).
	                                        From(MyContext.Company).
	                                        Where(MyContext.Company.ID.In(stmtSub));
                                        
两者是完全等价的。以这种方式开发者可以用Eql接口非常方便的构造出各种复杂程度的语句对象。
Copyright 2014--2020 广联科技版权所有