一步一步教你使用AgileEAS.NET基础类库进行应用开发-基础篇-ORM访问器及其配置

系列回顾

         本系列前面有三篇文章介绍和演示了AgileEAS.NET平台ORM组件的开发流程及其常见的使用方式,通过前面的三篇文章,大家都可以正常的使用ORM进行正常的开发,本文将提到一个ORM结构性的问题,ORM对象的访问器。

情况说明

         提到ORM访问器,我们就不得不提到一个面对对象设计的问题,那就是到底是对象.操作(),还是操作者.操作(对象),对于这样一个有着争论性并且也没有一个明确最优结果的问题,我也不敢在本文中详细的介绍,我将会在合适的时机发布一个讨论:面向对象设计中的对象.操作()还是操作者.操作(对象)。

访问模式变化

         AgileEAS.NET平台中的ORM最早是基于对象.操作()的这种思路设计的,在最初的版本中ORM实体对象(IEntity)和表对象(ITable)中包含了ORM的基本操作:读取、更新、删除、插件操作:

         我们可以IEntity的定义可以看到,实体记录接口定义了Query、Refresh、Inert、Update、Delete等与数据库同步的操作,也定义了CacheRefresh这样的缓存刷新操作,同样ITable对象也定义了他的操作:

         ITable接口定义了Query、Update、Delete等与数据库同步的操作,也定义了CacheQuery这样的缓存查询操作。

         在最初的ORM实现中,由ITable和IEntity的实现Table和Entity两个基类中直接实现这些方法,实质上在最高的ORM体系中就不存在ITable和IEntity接口,在那时还没有需要要求基于接口驱动。

         至今为止,ORM实体对象(IEntity和ITable)还包含着这一组方法的定义,在漫长的应用开发中prodct.Insert()这样的写法非常的普遍。

         在AgileEAS.NET平台ORM的变迁历史中,有两个事情改变了ORM对象及其访问器体系,第一件事是,同一应用要在不同数据库之上运行的需要驱动了基于接口驱动的数据层开发,也就是提出了ITable和IEntity接口,第二件事是SAAS/分布式应用环境催生了ORM访问器的诞生,进而实现了ORM组件定义与操作的分离。

         下面我们来看一看ORM访问器的定义IOrmAccessor:

         缓存访问器ICacheAccessor:

         平台目录在EAS.Data.dll程序中集内置了一个基于数据库连接的ORM访问器(OrmAccessor),他必须基于一个事实存在的数据库连接IConnection和IAccessor访问器,也内置了一个基于内存ORM缓存访问器(CacheAccessor)。

         同时,在AgileEAS.NET平台中实现了基于Remoting技术和WebService技术的分布式技术的分布式ORM访问器。

         有了ORM访问器,我们在应用开发过程中,就可以使用操作者.操纵(对象)这样的模式进行ORM操作,例如ormAccessor.Insert(product)。

两种模式的集成

          AgileEAS.NET平台中的ORM通过ORM访问器提供了操作者.操纵(对象)的这种处理模型,ORM在不同时期实现了这两种不同方法的处理,对于这两种方式,谁也无法说出那个具有决定的优点,一切都是相对的,在操作的方便性上,在面向对象的理论体系上。

          AgileEAS.NET平台中的ORM把实体的定义与访问进行了剥离,然后又把ORM对象与访问器进行了一个集成和粘合,即达到如下的结果:

          1.ORM即可以通过实体.操作()也可以通过访问器.操纵(实体)完成对ORM实体的操纵。

          2.分离ORM实体对象的操作代码,保在ORM实体对象中保留与实体定义相关的代码,实体对象上定义OrmAccessor属性,实现上的操作方法调用Orm访问器的实体操作方法。

          3.ORM实体对象与ORM访问器接口偶尔,基于接口驱动,通过代码或者配置,在运行时使用不同的访问器实现。

          在实际使用中我发两段等效代码:

    /// <summary>
    /// 输出全表数据
    /// </summary>
    public void DemoQuery()
    {
        ProductList table = new ProductList();
        OrmContext.OrmAccessor.Query(table);
        int cols = table.Columns.Count;
        foreach (Product product in table.Rows)
        {
            //do
        }
    }       

          等同于:

    /// <summary>
    /// 输出全表数据
    /// </summary>
    public void DemoQuery()
    {
        ProductList table = new ProductList();
        table.OrmAccessor = OrmContext.OrmAccessor;
        table.Query();
        int cols = table.Columns.Count;
        foreach (Product product in table.Rows)
        {
            //do
        }
    }        

访问器配置

         之前ORM演示的例子我对ORM访问器使用报一个OrmContext进行了声明,在OrmContext类中,对Orm访问器使用直接new的方式进行了实例化:

    /// <summary>
    /// Orm访问器。
    /// </summary>
    public static IOrmAccessor OrmAccessor
    {
        get
        {
            if (Instance.ormAccessor == null)
            {
                Instance.ormAccessor = new OrmAccessor();
                Instance.ormAccessor.DataAccessor = DataAccessor;
            }

            return Instance.ormAccessor;
        }
    }

         从代码中我们看到Instance.ormAccessor = new OrmAccessor(),这样一来应用业务与访问器的实现进行了耦合,Instance.ormAccessor.DataAccessor = DataAccessor; 这一句完成ORM访问器所依赖的数据访问器的注入,程序并没有有效的解耦。

        解决这个问题的办法,还是老方法,使用AgileEAS.NET平台的控制反转(IOC)组件来完成访问器的解耦,有关AgileEAS.NET平台IOC组件的介绍请参见AgileEAS.NET平台之对象控制反转一文。

        首先我们用以下代码替换OrmContext类:

 1     static class OrmContext
 2     {
 3         /// <summary>
 4         /// Orm访问器。
 5         /// </summary>
 6         public static IOrmAccessor OrmAccessor
 7         {
 8             get
 9             {
10                 return ContextHelper.GetContext().Container.GetComponentInstance("OrmAccessor") as IOrmAccessor;
11             }
12         }
13     }

         向ClassLib.OrmDemo项目添加一个应用程序配置文件app.config,并写如以下信息:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <configuration>
 3  <configSections>
 4  <section name="EAS.Objects" type="EAS.Objects.ConfigHandler,EAS.IOCContainer"/>
 5  </configSections>
 6  <EAS.Objects>
 7  <object name="DataConnection" assembly="EAS.Data" type="EAS.Data.Access.SqlClientConnection" LifestyleType="Singleton">
 8  <property name="ConnectionString" type="string" value="Data Source=vm2003;Initial Catalog=eas;User ID=sa" />
 9  </object>
10  <object name="OrmAccessor" assembly="EAS.Data" type="EAS.Data.ORM.OrmAccessor" LifestyleType="Singleton">
11  <property name="DbConnection" type="object" value="DataConnection" />
12  </object>
13  <!--<object name="CacheAccessor" assembly="EAS.Data" type="EAS.Data.ORM.CacheAccessor" LifestyleType="Singleton">
14         </object>-->
15  <object name="DataAccessor" assembly="EAS.Data" type="EAS.Data.Access.SqlClientAccessor" LifestyleType="Singleton">
16  <property name="Connection" type="object" value="DataConnection" />
17  </object>
18  </EAS.Objects>
19 </configuration>

         重新编译运行,结束本次演示,在一步篇文章中我将介绍ORM中使用SQL语句实现ORM不能实现的特定业务。  

        有关本例子所涉及的数据表结构请参考基于AgileEAS.NET平台基础类库进行应用开发-总体说明及数据定义一文,有关数据对象模型定义文件、文档、DDL脚本请下载:http://files.cnblogs.com/eastjade/demo.db.doc.sql.rar,本文代码下载:ORM.Demo4.rar。 

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏帘卷西风的专栏

mysql 大小写敏感的一个解决方案

     今天,有同事告诉我,我们游戏登陆的时候,账号和密码没有区分大小写,后来又发现创建账号和角色也没有区分大小写。思考登陆流程之后,应该是Mysql没有区分...

19510
来自专栏Java技术分享

30天轻松掌握JavaWeb-学习目录

17.使用beanUtils操纵javabean

27860
来自专栏CRPER折腾记

Vue折腾记 - (2)写一个不大靠谱的面包屑组件

我把页面标题和面包屑封装到一起..就不用涉及到组件的通讯了, 不然又要去监听路由或者依赖状态去获取

16820
来自专栏数据和云

性能分析:Oracle的CLOB使用与临时段访问及其性能优化

编辑手记:在系统测试、上线和优化的过程中,抓住核心环节、不放过任何可疑,这是DBA的基本要求之一,在这个案例中,高频度调用的存储过程引起了注意。 客户新上线的一...

51750
来自专栏枕边书

搭建自己的PHP框架心得(一)

前言 说到写PHP的MVC框架,大家想到的第一个词--“造轮子”,是的,一个还没有深厚功力的程序员,写出的PHP框架肯定不如那些出自大神们之手、经过时间和各种项...

42270
来自专栏Small Code

MATLAB批量文件重命名(详细解释)

这段时间在用 matlab 做手写数字识别,处理样本的时候需要对样本文件进行重命名,可是有好多,总不能一个一个重命名吧,于是上网百度了好多,不过大多都一样,但是...

36870
来自专栏FreeBuf

构造优质上传漏洞Fuzz字典

上传漏洞的利用姿势很多,同时也会因为语言,中间件,操作系统的不同,利用也不同。比如有:大小写混合,.htaccess,解析漏洞,00截断,.绕过,空格绕过,::...

28830
来自专栏IT技术精选文摘

从Java视角理解系统结构(三)伪共享

从我的前一篇博文中, 我们知道了CPU缓存及缓存行的概念, 同时用一个例子说明了编写单线程Java代码时应该注意的问题. 下面我们讨论更为复杂, 而且更符合现实...

22170
来自专栏码农分享

推荐一个有用的Excel操作类库 LinqToExcel

以前项目中对Excel进行信息读取,我都是使用的NPOI的封装类,给定一个fileurl,然后返回给我一个datatable。接下去自己去解析数据。如果使用这种...

20620
来自专栏老九学堂

从Hello World说程序运行机制

学习任何一门编程语言,都会从Hello World 开始。对于一门从未接触过的语言,在短时间内我们都能用这种语言写出它的Hello World。然而,对于Hel...

41280

扫码关注云+社区

领取腾讯云代金券