DataRabbit 轻量的数据访问框架(04) -- IEntityRelationLoader

  (完全限定类名:DataRabbit.ORM.IEntityRelationLoader)

   在DataRabbit框架提供的ORM功能之中,除了IOrmAccesser接口展现的核心ORM功能外,IEntityRelationLoader接口也提供了一些有意义的功能。正如其名,IEntityRelationLoader是通过数据表的主外键关系来加载当前Entity的Parent和Children。

   现在对我们前面示例经常用到的Student数据表做个扩充,假设,Student表的MentorID字段作为外键,指向Mentor表;而且,Book表中的StudentID字段也是外键,指向Student表。这种主外键关系的含义是:“一个学生有一个导师,并且拥有多本书”。这三个表的关系图如下所示:

   通过对Student扩充后,我们可以为Student Entity Class 加上如下两个属性,来反映这种关系:
 

        #region Mentor
        [NonSerialized]
        private Mentor m_Mentor = null ; 
        public Mentor Mentor
        {
            get
            {
                return this.m_Mentor ;
            }
            set
            {
                this.m_Mentor = value ;
            }
        }
        #endregion

        #region BookList
        [NonSerialized]
        private IList<Book> m_BookList = null ; 
        public IList<Book> BookList
        {
            get
            {
                return this.m_BookList ;
            }
            set
            {
                this.m_BookList = value ;
            }
        }
        #endregion
      

   我将这种通过主外键关系得到的属性称为“FamilyRelation”属性,如果使用EntityCreator工具生成Entity Class,这些属性都会根据数据表关系而自动生成。

   现在,我们来调用如下语句:

    Student student = stuOrmAccesser.GetOne(new Filter(Student._ID, 30));        

   结果会发现,返回的student对象的Mentor属性和BookList属性不会被填充。如果不使用IEntityRelationLoader接口,而是直接通过IOrmAccesser来获取这个student的“Family”,我们需要这样做:

    Student student = stuOrmAccesser.GetOne(new Filter(Student._ID, 30));
    student.Mentor = stuOrmAccesser.GetParent<Mentor>(student);
    student.BookList = stuOrmAccesser.GetChildList<Book>(student);

   像这样子可以达到目的,但是未免繁琐了一点,如果Student表有多个外键,则我们就要调用多次GetParent()方法来分别获取各个Parent;对于多个Children,也是如此。IEntityRelationLoader接口使得这种基于关系的加载变得非常简单,如上述功能使用下面的代码即可实现:

   entityRelationLoader.LoadFamily(student);
   LoadFamily方法一次调用可以加载当前student对象的所有“Family”成员(注意,这里的加载“Family”只包括加载自己Parent和Children,而不包括更上的grandfather或更下的grandson等)。

    我们可以从DataRabbit的入口点IDataAccesser接口获取IEntityRelationLoader引用:

   IEntityRelationLoader entityRelationLoader = dataAccesser.GetEntityRelationLoader(null);

    
   通过上面的示例,我们对IEntityRelationLoader的功能已经有了一些了解。下面我们来看看这个接口的全貌:

    public interface IEntityRelationLoader :ITransactionAccesser
    {
        /// <summary>
        /// LoadChildren 加载自己的children到对应的属性字段(如果Entity提供了这些属性字段,并且属性可写)上。
        /// </summary>  
        void LoadChildren(object entity);

        /// <summary>
        /// LoadParents 加载自己的parents到对应的属性字段(如果Entity提供了这些属性字段,并且属性可写)上。
        /// </summary>
        void LoadParents(object entity);

        /// <summary>
        /// LoadFamily 加载自己的parents和children到对应的属性字段(如果Entity提供了这些属性字段,并且属性可写)上。
        /// </summary>        
        void LoadFamily(object entity);

        /// <summary>
        /// LoadOffspring 以当前entity为根,加载所有后代。注意,自己以及后代的所有Parent属性都不会被赋值。
        /// </summary>  
        void LoadOffspring(object entity);       
    }

转到:DataRabbit 轻量的数据访问框架 -- 序

时间: 2024-10-22 22:16:44

DataRabbit 轻量的数据访问框架(04) -- IEntityRelationLoader的相关文章

DataRabbit 轻量的数据访问框架(09) -- IDataSchemaAccesser

   (完全限定类名:DataRabbit.Schema.IDataSchemaAccesser)    在前面介绍的很多访问器的实现中,都不需要使用者提供任何关于数据库表结构的信息(比如,主键.主外键关系等),这是因为它们都借助于IDataSchemaAccesser来获取目标数据表的大纲信息,本文就来介绍如何使用DataRabbit框架中的IDataSchemaAccesser来访问和操作数据表的大纲.    我们可以从DataRabbit的入口点IDataAccesser中获取IDataS

DataRabbit 轻量的数据访问框架(10) -- IPagerManager

   (完全限定类名:DataRabbit.Core.IPagerManager)    DataRabbit框架提供了对单表查询的结果进行分页的功能,这就是IPagerManager所完成的目标.我们可以从DataRabbit的入口点IDataAccesser中获取IPagerManager引用:     PagerParameters param = ...; //构建分页参数    IPagerManager pagerManager= dataAccesser.GetPagerManag

DataRabbit 轻量的数据访问框架(06) -- IRelationAccesser

   (完全限定类名:DataRabbit.Relation.IRelationAccesser)       前面介绍的IOrmAccesser是对单表进行ORM访问,而ITableAccesser是对单表进行基于关系的访问,如果我们要进行联合查询这样的跨表搜索,则使用它们就无法达成目标.这时,你可以使用IRelationAccesser.与IOrmAccesser和ITableAccesser的针对性不同(它们针对数据库中的某个表),IRelationAccesser针对的是整个目标数据库.

DataRabbit 轻量的数据访问框架(07) -- ISPAccesser

   (完全限定类名:DataRabbit.Relation.ISPAccesser)       虽然IRelationAccesser可以调用一些不含out参数的存储过程,但是在DataRabbit中调用存储过程最好是通过ISPAccesser接口来进行.   存储过程不仅可以有返回值,还可以有[in,out]参数,在对存储过程的调用进行封装之前,首先必须抽象存储过程的参数表示.DataRabbit使用SPParameter来表示存储过程的参数.   注意,Name属性表示参数名,该参数名不

DataRabbit 轻量的数据访问框架(13)--DataRabbit 3.0 ORM性能大幅度提升!

   DataRabbit 3.0重写了DataRabbit 2.0的ORM实现的内核,性能提升了90倍左右,结果是DataRabbit 3.0的ORM性能与直接使用ADO.NET的性能已经非常接近.这是如何做到的?   主要是基于两点:(1)DataRabbit 2.0 基于泛型和反射实现,而DataRabbit 3.0 基于泛型和Emit动态程序集实现.   DataRabbit 2.0使用反射机制将值在O和R之间传递,如此大量使用反射会使性能折损不少.DataRabbit 3.0在运行时,

DataRabbit 轻量的数据访问框架(03) -- IOrmAccesser(续)

   本文将接着 DataRabbit 轻量的数据访问框架 -- IOrmAccesser 继续介绍IOrmAccesser的一些高级功能.这些高级功能需要DataRabbit.ORM.ISmartEntity接口的支持.注意,对于Entity class 来说,该接口并不是强制的. (1)关于含自增字段的Entity插入:      插入后,Entity中对应自增字段的属性将被正确地赋为数据库中自增结果值.    如果Entity class 继承了ISmartEntity接口,那么这个Ent

DataRabbit 轻量的数据访问框架(08) -- DataRabbit 的入口点:TransactionScopeFactory和TransactionScope

   (完全限定类名:DataRabbit.Application.TransactionScopeFactory ,DataRabbit.Application.TransactionScope)            关于TransactionScopeFactory首先要提醒以下几点: (1)TransactionScopeFactory是DataRabbit框架的入口点,所有的访问器.分页管理器.大纲操作者都可以从TransactionScopeFactory生成的Transaction

DataRabbit 轻量的数据访问框架(05) -- ITableAccesser

   (完全限定类名:DataRabbit.Relation.ITableAccesser)       ORM并不能完成所有的事情,有些数据库访问还是需要基于关系来进行,对于那些不提供基于关系进行数据访问操作的纯ORM框架,我认为是不明智的.在DataRabbit中,基于ORM的访问和基于关系进行数据访问各占了一半的天空,这使得我们在无法用ORM达成的地方,可以转向使用基于关系的访问器来达成.DataRabbit.Relation命名空间下的类和接口用于提供基于关系的数据库访问操作,主要包括:

DataRabbit 轻量的数据访问框架(15)-- IOrmAccesser的BatchInsert批量插入!

   DataRabbit3.0为ORM访问器提供了批量插入的功能,其方法定义如下:         /// <summary>        /// BatchInsert 批量插入一组记录.忽略所有Blob字段.        /// </summary>               void BatchInsert(IList<EntityType> entityList);     当我们需要一次性向同一Table中插入大量(如千条以上)的记录时,使用Batch