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

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

   在DataRabbit框架中,通过IOrmAccesser来对数据库进行ORM访问,只要Entity(即ORM中的“O”)的定义与数据库表的结构完全一致,即可使用IOrmAccesser来对其进行ORM操作。

1.Entity
   Entity除了包括成员变量与属性(这些变量与属性与数据库表的结构完全一致)外,不需要包含任何其它元素。在轻量的数据访问框架 --序 的例子代码中,我们已经看到了一个Student Entity的示例。

2.Filter
   我们经常需要依据条件来搜索数据,在DataRabbit的ORM框架中,使用Filter来表示一个单独的条件。Filter从ColumnItem继承,ColumnItem 表示数据列及其对应的值。比如,在进行Update操作时,我们可以使用一个ColumnItem 的List来指定要将哪些列的值更新为指定的值。

   首先,注意,Filter中包含一个GetBooleanExpression()方法,该方法将当前Filter转换为一个标准的Sql条件字句。
   Filter的ComparisonOperator属性表明了采用何种比较符来构建条件表达式。

ComparisonOperators
    [EnumDescription("比较操作符")]
    public enum ComparisonOperators
    {
        [EnumDescription("=")]
        Equal ,
        [EnumDescription("!=")]
        NotEqual ,
        [EnumDescription(">")]
        Greater ,
        [EnumDescription("<")]
        Less ,
        [EnumDescription(">=")]
        NotLessThan,
        [EnumDescription("<=")]
        NotGreaterThan,
        [EnumDescription(" like ")]
        Like
    }

   在IOrmAccesser接口中,很多方法都接受 params Filter[] conditions 或IList<Filter>参数,比如:

        void Delete(IList<Filter> conditions);
        void Delete(params Filter[] conditions);

   比如,要删除数据库Student表中所有Age大于20岁且为男性的学生记录

 stuOrmAccesser.Delete(new Filter(Student._Age, 20, ComparisonOperators.Greater), new Filter(Student._IsBoy, true, ComparisonOperators.Equal));

   
   针对接受 params Filter[] conditions 或IList<Filter>参数的方法,在OrmAccesser内部将会对每个Filter所表示的单个条件进行“与”操作,来作为搜索条件。那么如果需要对各个Filter进行“或”操作,或进行更复杂的逻辑组合(如“filter1 && (filter2 || filter3)”),就需要采用对应的接受IFilterTree作为参数的重载方法。

3.IFilterTree
   IFilterTree 用于表示多个Filter的逻辑组合。
   
   注意,IFilterTree中也包含一个GetBooleanExpression()方法,该方法将当前Filter通过逻辑组合转换为一个标准的Sql条件字句。
   当前的IFilterTree有两个默认实现:
(1)SimpleFilterTree
   该实现仅仅支持最简单的对多个条件都进行“与”或都进行“或”的逻辑操作,更复杂的逻辑组合需求,可以使用AgileFilterTree。
   如果将上述的例子,改用IFilterTree可以这样实现:

            IList<Filter> conditions = new List<Filter>();
            conditions.Add(new Filter(Student._Age, 20, ComparisonOperators.Greater));
            conditions.Add(new Filter(Student._IsBoy, true, ComparisonOperators.Equal));
            IFilterTree conditionTree = new SimpleFilterTree(LogicType.And, conditions);
            stuOrmAccesser.Delete(conditionTree);

(2)AgileFilterTree
   AgileFilterTree 可以表示非常复杂的多个Filter的逻辑组合。它使用一个logicExpression字符串描述逻辑组合表达式,如"filter1 && (filter2 || filter3)",然后解析这个表达式获取正确的Sql条件语句。
   比如,我们要找出所有年龄在20与25岁之间,或者名字为sky的学生:

            IDictionary<string, Filter> mapping = new Dictionary<string, Filter>();
            mapping.Add("A", new Filter(Student._Name, "sky", ComparisonOperators.Equal));
            mapping.Add("B", new Filter(Student._Age, 20, ComparisonOperators.Greater));
            mapping.Add("C", new Filter(Student._Age, 25, ComparisonOperators.Less));
            IFilterTree agileTree = new AgileFilterTree("A||(B&&C)", mapping);

            IList<Student> list = stuOrmAccesser.GetMuch(agileTree);

4.IOrmAccesser的泛型参数
   IOrmAccesser是一个泛型接口,泛型参数是EntityType--即实体的类型,我们知道,每个EntityType对应着数据库中的一个表,Entity class的名字最好与数据表的名字一致,这样IOrmAccesser就可以根据EntityType知道要访问数据库中的哪个表。如果Entity class的名字最好与数据表的名字不一致,也没关系,我们可以通过向IDataAccesser的OrmCoagent属性注入IOrmCoagent来提供EntityType与数据表名称的映射关系。IOrmCoagent接口定义如下:

    public interface IOrmCoagent
    {
        /// <summary>
        /// GetTableName 根据Entity类型获取对应的数据库表名
        /// </summary>        
        string GetTableName(Type entityType);
    }

   IOrmAccesser可以通过IOrmCoagent的GetTableName()方法来获取EntityType所对应的数据库表的名称。

5.基本"CRUD"方法

   IOrmAccesser提供了基本的“CRUD”方法,如Insert,Update,Delete,GetOne,GetMuch,GetDataSet等等。这些方法都提供了多个重载,以接收单个Filter条件或多个Filter以及IFilterTree。
   大多数方法的含义都特别清晰明了,有几个方法的含义需要特别指出一下:

        /// <summary>
        /// GetMuchWithoutBlob 根据参数conditions来提取符合条件的所有Entity,但是Entity的blob字段没有被填充。
        /// </summary>        
        IList<EntityType> GetMuchWithoutBlob(params Filter[] conditions);

        /// <summary>
        /// LoadBlob 填充entity的Blob字段
        /// </summary>        
        void LoadBlob(EntityType entity);

        /// <summary>
        /// Update 更新符合conditions的记录中由columnItems指定的各个Column为对应目标值。
        /// </summary>        
        void Update(IList<ColumnItem> columnItems, IList<Filter> conditions);

        /// <summary>
        /// GetDataSet 选取表中符合条件的row,并且只返回columns指定的列。
        /// </summary>      
        DataSet GetDataSet(IList<Filter> conditions, params string[] columns);

6.基于主外键关系进行Get获取
    IOrmAccesser会自动依据数据表的主外键关系来进行关系加载,比如,Student表中有MentorID字段(外键),对应Mentor表中的主键。那么,IOrmAccesser的GetParent方法,就可以根据指定的Student对象返回Mentor对象。

Mentor mentor = stuOrmAccesser.GetParent<Mentor>(student);

基于主外键关系进行Get的方法包括:

        /// <summary>
        /// GetParent 依据entity中外键的值,获取主表中的实体。外键建立了"语义"上的"Master-Detail"关系
        /// </summary>       
        ParentType GetParent<ParentType>(EntityType entity);

        /// <summary>
        /// GetForeigner 依据entity中名为fkeyName外键的值,获取主表中的对应实体。外键没有"语义"上的"Master-Detail"关系
        /// </summary>       
        ForeignerType GetForeigner<ForeignerType>(EntityType entity ,string fkeyName);

        /// <summary>
        /// GetChildList 依据entity中主键的值,获取从表中的所有相关实体
        /// </summary>
        IList<ChildType> GetChildList<ChildType>(EntityType entity);

        /// <summary>
        /// GetChildDataSet 依据entity中主键的值,获取从表中的所有相关记录
        /// </summary>
        DataSet GetChildDataSet<ChildType>(EntityType entity);
        #endregion

   本文简单介绍了IOrmAccesser的一些基本功能和使用,在后面的文章中将介绍一些IOrmAccesser高级用法

返回到:轻量的数据访问框架 --序  

 

 

时间: 2024-10-12 06:11:26

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

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 轻量的数据访问框架(04) -- IEntityRelationLoader

  (完全限定类名:DataRabbit.ORM.IEntityRelationLoader)    在DataRabbit框架提供的ORM功能之中,除了IOrmAccesser接口展现的核心ORM功能外,IEntityRelationLoader接口也提供了一些有意义的功能.正如其名,IEntityRelationLoader是通过数据表的主外键关系来加载当前Entity的Parent和Children.    现在对我们前面示例经常用到的Student数据表做个扩充,假设,Student表的

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

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