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

   本文将接着 DataRabbit 轻量的数据访问框架 -- IOrmAccesser 继续介绍IOrmAccesser的一些高级功能。这些高级功能需要DataRabbit.ORM.ISmartEntity接口的支持。注意,对于Entity class 来说,该接口并不是强制的。

(1)关于含自增字段的Entity插入

     插入后,Entity中对应自增字段的属性将被正确地赋为数据库中自增结果值。

   如果Entity class 继承了ISmartEntity接口,那么这个Entity就是一个“Smart”的Entity,IOrmAccesser针对这样的Entity,它将拥有两种特殊的能力:
(2)partial update:即部分更新的功能。即在Update一个SmartEntity对象时,只更新哪些标记为“dirty”的字段。
   比如,我们以前这样来实现“将ID为30的学生的Email更新”的功能:

            //将ID为30的学生的Email更新
            Student student = stuOrmAccesser.GetOne(new Filter(Student._ID, 30));        
            student.Email = "sky@299.com";
            stuOrmAccesser.Update(student);//更新除主键外的所有字段

   但是,如果Student Entity实现了ISmartEntity接口,就可以这么做:

            //将ID为30的学生的Email更新
            Student student = new Student() ;
            student.ID = 30 ;
            student.Email = "sky@299.com";
            stuOrmAccesser.Update(student);//仅仅更新“Email”字段

   由于指讲“Email”字段标记为“dirty”,所以在Update时,仅仅会更新“Email”字段的值。

(3)插入前检查:即在向数据库中插入一个SmartEntity对象之前,先检查该对象的状态是否正确,如果不正确,将不会插入,而是抛出InvalidEntityException异常。

   ISmartEntity接口定义与说明如下:

    public interface ISmartEntity
    {
        /// <summary>
        /// Clean 将所有Column字段的dirty标记设为false。
        /// </summary>
        void Clean();

        /// <summary>
        /// DirtyColumnList 获取所有需要更新的Column
        /// </summary>
        IList<string> DirtyColumnList { get; }

        /// <summary>
        /// Check 用于检查Entity内部状态是否一致。
        /// 在将ISmartEntity插入(或更新)到数据库之前,DataRabbit会检查(Check)其状态是否有效,如果无效,则将抛出InvalidEntityException。
        /// </summary>      
        bool Check(DataAccessType dataAccessType);
    }

    /// <summary>
    /// DataAccessType 访问数据库的几种操作类型
    /// </summary>
    public enum DataAccessType
    {
        Query, Insert, Update, Delete
    }

   
   普通的Entity class可以通过工具自动生成,smart Entity class也可以通过工具自动生成,我写了一个简单的小工具“EntityCreator”来生成Entity class或smart Entity class。生成的Entity class代码中,Check()方法直接返回true,我们可以在这个方法内添加代码以检查当前Entity对象的状态,确保在插入该对象之前,对象的状态是一致、正确的。
   下面是针对前述的Student生成的smart Entity 代码:

Student
[Serializable]
    public partial class Student :ISmartEntity 
    {
    
        #region Force Static Check
        public const string TableName = "Student" ;
        public const string _ID = "ID" ;
        public const string _Name = "Name" ;
        public const string _Age = "Age" ;
        public const string _MentorID = "MentorID" ;
        public const string _Email = "Email" ;
        public const string _IsBoy = "IsBoy" ;
        #endregion
    
        #region Property
    
        #region ID
        private System.Int32 m_ID = 0 ; 
        public System.Int32 ID
        {
            get
            {
                return this.m_ID ;
            }
            set
            {
                if (!this.dirtyColumnList.Contains("ID"))
                {
                    this.dirtyColumnList.Add("ID");
                }
                this.m_ID = value ;
            }
        }
        #endregion
    
        #region Name
        private System.String m_Name = "" ; 
        public System.String Name
        {
            get
            {
                return this.m_Name ;
            }
            set
            {
                if (!this.dirtyColumnList.Contains("Name"))
                {
                    this.dirtyColumnList.Add("Name");
                }
                this.m_Name = value ;
            }
        }
        #endregion
    
        #region Age
        private System.Int32 m_Age = 0 ; 
        public System.Int32 Age
        {
            get
            {
                return this.m_Age ;
            }
            set
            {
                if (!this.dirtyColumnList.Contains("Age"))
                {
                    this.dirtyColumnList.Add("Age");
                }
                this.m_Age = value ;
            }
        }
        #endregion
    
        #region MentorID
        private System.Int32 m_MentorID = 0 ; 
        public System.Int32 MentorID
        {
            get
            {
                return this.m_MentorID ;
            }
            set
            {
                if (!this.dirtyColumnList.Contains("MentorID"))
                {
                    this.dirtyColumnList.Add("MentorID");
                }
                this.m_MentorID = value ;
            }
        }
        #endregion
    
        #region Email
        private System.String m_Email = "" ; 
        public System.String Email
        {
            get
            {
                return this.m_Email ;
            }
            set
            {
                if (!this.dirtyColumnList.Contains("Email"))
                {
                    this.dirtyColumnList.Add("Email");
                }
                this.m_Email = value ;
            }
        }
        #endregion
    
        #region IsBoy
        private System.Boolean m_IsBoy = false ; 
        public System.Boolean IsBoy
        {
            get
            {
                return this.m_IsBoy ;
            }
            set
            {
                if (!this.dirtyColumnList.Contains("IsBoy"))
                {
                    this.dirtyColumnList.Add("IsBoy");
                }
                this.m_IsBoy = value ;
            }
        }
        #endregion
        #endregion        
        
        #region ISmartEntity members
        
        #region DirtyColumnList
        [NonSerialized]
        private IList<string> dirtyColumnList = new List<string>();
        public IList<string> DirtyColumnList
        {
            get { return dirtyColumnList; }
        }
        #endregion
        
        #region Clean
        public void Clean()
        {
            this.dirtyColumnList.Clear();
        }
        #endregion
        
        #region Check 
        public bool Check(DataAccessType dataAccessType)
        {
            //可在此添加自己的Entity状态验证逻辑
            return true ;
        }
        #endregion
        #endregion
        
        #region ToString 
        public override string ToString()
        {
            return this.ID.ToString()  + " " + this.Name.ToString() ;
        }
        #endregion
    }

   最后,提供EntityCreator小工具的下载。

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

时间: 2024-09-12 06:28:38

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